1. RE: [Windows] Associate file extensions with a program

Matt Lewis wrote:
> 
> 
> posted by: Matt Lewis <matthewwalkerlewis at yahoo.com>
> 
> Pete Lomax wrote:
> > 
> > Juergen Luethje wrote:
> > 
> > > I can see that implementation #1 is not a good idea, but what about
> > > implementation #2?
> >
> > If there is an error in proc1, such as FileDoesNotExist, then it would
> > not help matters to replace this with ErrorWritingToFile in proc2.
> > 
> > In fact, wouldn't most error conditions tend to daisy-chain?
> 
> Yes.  It's important to allow for errors to propagate back up through
> the call chain.  I've done this a couple of different ways in EuSQL and
> in matheval.  In EuSQL, all functions return a sequence on success, and 
> an integer on failure.  After pretty much every call from a library 
> routine to another, I check this condition, and simply return the error
> code.  There is also an extended error message that can be set, and that
> an application can request.
> 
> In matheval, I defined a separate type, called INVALID.  Each matheval
> type is smart enough to only operate on other types that it understands,
> so the INVALID type is simply passed back.  Part of the INVALID type is
> an error message.
> 
> Matt Lewis

What you want is error trapping and exception handling.

I've written a library to deal with this..
It's not perfect, because we can't bail out of the call stack, but
otherwise, it's a good solution for error trapping.
Note also, that error trapping puts the sanity tests into the routines
that are actually making the errors. That is how it should be.
Error trapping also keeps the routine's result unambiguous.

here is a psuedo-example...
------------------------------------
allow_error_trapping(OFF)
allow_pending_errors(OFF)

constant ERR_FOPEN = define_error(NULL)
function fopen(sequence name, sequence flags)
  integer fn
   if fn = -1 then
     throw_error(ERR_FOPEN,"Failed to open "&name&" with the flags:
\'"*flags&"\'\n")
   end if
   return fn
end function

-- now I can do stuff like this..
integer fn1,fn2,fn3,fn4,fn5
fn1 = fopen("foo1.txt","rb")
fn2 = fopen("foo2.txt","rb")
fn3 = fopen("foo3.txt","rb")
fn4 = fopen("foo4.txt","rb")
fn5 = fopen("foo5.txt","rb")
trap_error(ERR_FOPEN)
----------------------------------------
In that specific example, trap_error() is not even needed at all.

If allow_error_trapping() is OFF, allow_pending_errors() has no affect.

With allow_error_trapping(OFF), each error is thrown and called
immmediately. throw_error() acts like a regular error msg routine.
For example, if foo1.txt fails.. the error occurs immediately within
fopen()

With allow_error_trapping(ON), and allow_pending_errors(OFF), each error
is thrown, but is not called unless an error is already pending.
For example, if foo1.txt fails, and foo3.txt fails, the error will be
thrown for foo1.txt when the error for foo3.txt is discovered.

With allow_error_trapping(ON) and allow_pending_errors(ON), each error
is thrown, and only called via trap_error()
For example, if foo1.txt fails, and foo3.txt fails.
Eu will still process each fopen statement. When it reaches, and calls
trap_error(ERR_FOPEN), it checks for any pending errors, matching that
ERR_FOPEN, and calls the first occurance. (An error would be
instantiated for foo1.txt)

The library does much more than I have described. Such as the ability to
define custom error handlers for each error code, the ability to catch,
drop, fetch and intercept exceptions, and some other lower level error
routines.

I'll share it with anyone interested. I'm not going to post it, because
the code is written for my own libraries, and isn't compatible with the
official rds libraries. There also isn't any documentation. If there is
anyone interested, I can port it back for them, and whip up some docs.


Chris Bensler
Code is Alchemy

new topic     » topic index » view message » categorize

2. RE: [Windows] Associate file extensions with a program

Chris Bensler wrote:
> 
> What you want is error trapping and exception handling.
> 
> I've written a library to deal with this..
> It's not perfect, because we can't bail out of the call stack, but
> otherwise, it's a good solution for error trapping.
> Note also, that error trapping puts the sanity tests into the routines
> that are actually making the errors. That is how it should be.
> Error trapping also keeps the routine's result unambiguous.
> 
> here is a psuedo-example...
> ------------------------------------
> allow_error_trapping(OFF)
> allow_pending_errors(OFF)
> 
> constant ERR_FOPEN = define_error(NULL)
> function fopen(sequence name, sequence flags)
>   integer fn
>    if fn = -1 then
>      throw_error(ERR_FOPEN,"Failed to open "&name&" with the flags:
> \'"*flags&"\'\n")
>    end if
>    return fn
> end function
> 
> -- now I can do stuff like this..
> integer fn1,fn2,fn3,fn4,fn5
> fn1 = fopen("foo1.txt","rb")
> fn2 = fopen("foo2.txt","rb")
> fn3 = fopen("foo3.txt","rb")
> fn4 = fopen("foo4.txt","rb")
> fn5 = fopen("foo5.txt","rb")
> trap_error(ERR_FOPEN)
> ----------------------------------------
> In that specific example, trap_error() is not even needed at all.
> 
> If allow_error_trapping() is OFF, allow_pending_errors() has no affect.
> 
> With allow_error_trapping(OFF), each error is thrown and called
> immmediately. throw_error() acts like a regular error msg routine.
> For example, if foo1.txt fails.. the error occurs immediately within
> fopen()
> 
> With allow_error_trapping(ON), and allow_pending_errors(OFF), each error
> is thrown, but is not called unless an error is already pending.
> For example, if foo1.txt fails, and foo3.txt fails, the error will be
> thrown for foo1.txt when the error for foo3.txt is discovered.
> 
> With allow_error_trapping(ON) and allow_pending_errors(ON), each error
> is thrown, and only called via trap_error()
> For example, if foo1.txt fails, and foo3.txt fails.
> Eu will still process each fopen statement. When it reaches, and calls
> trap_error(ERR_FOPEN), it checks for any pending errors, matching that
> ERR_FOPEN, and calls the first occurance. (An error would be
> instantiated for foo1.txt)

This seems very similar with the error handling I use in EuSQL (except
that it has to bail out of the call stack).  There's even an 'automatic' 
way, using a user defined type (EUSQLRESULT), to get errors reported to 
the user, and this can cause the app to shut down or not (user-defined).  
I tend to use it for debugging and testing mostly, since it shuts down 
and allows me to see where things went wrong.

I assume there must be a way to get at the error information in your
library.  How do you recover from an error (i.e., what would you do if 
foo1.txt didn't open, but you needed it to continue)?

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

3. RE: [Windows] Associate file extensions with a program

Matt Lewis wrote:
> 
> 
> posted by: Matt Lewis <matthewwalkerlewis at yahoo.com>
> 
> Chris Bensler wrote:
> > 
> > What you want is error trapping and exception handling.
> > 
> > I've written a library to deal with this..
> > It's not perfect, because we can't bail out of the call stack, but
> > otherwise, it's a good solution for error trapping.
> > Note also, that error trapping puts the sanity tests into the routines
> > that are actually making the errors. That is how it should be.
> > Error trapping also keeps the routine's result unambiguous.
> > 
> > here is a psuedo-example...
> > 
> > constant ERR_FOPEN = define_error(NULL)
> > function fopen(sequence name, sequence flags)
> >   integer fn
> >    if fn = -1 then
> >      throw_error(ERR_FOPEN,"Failed to open "&name&" with the flags:
> > \'"*flags&"\'\n")
> >    end if
> >    return fn
> > end function
> > 
> > -- now I can do stuff like this..
> > integer fn1,fn2,fn3,fn4,fn5
> > fn1 = fopen("foo1.txt","rb")
> > fn2 = fopen("foo2.txt","rb")
> > fn3 = fopen("foo3.txt","rb")
> > fn4 = fopen("foo4.txt","rb")
> > fn5 = fopen("foo5.txt","rb")
> > trap_error(ERR_FOPEN)
> > 
> > If allow_error_trapping() is OFF, allow_pending_errors() has no affect.
> > 
> > With allow_error_trapping(OFF), each error is thrown and called
> > immmediately. throw_error() acts like a regular error msg routine.
> > For example, if foo1.txt fails.. the error occurs immediately within
> > fopen()
> > 
> > With allow_error_trapping(ON), and allow_pending_errors(OFF), each error
> > is thrown, but is not called unless an error is already pending.
> > For example, if foo1.txt fails, and foo3.txt fails, the error will be
> > thrown for foo1.txt when the error for foo3.txt is discovered.
> > 
> > With allow_error_trapping(ON) and allow_pending_errors(ON), each error
> > is thrown, and only called via trap_error()
> > For example, if foo1.txt fails, and foo3.txt fails.
> > Eu will still process each fopen statement. When it reaches, and calls
> > trap_error(ERR_FOPEN), it checks for any pending errors, matching that
> > ERR_FOPEN, and calls the first occurance. (An error would be
> > instantiated for foo1.txt)
> 
> This seems very similar with the error handling I use in EuSQL (except
> that it has to bail out of the call stack).  There's even an 'automatic' 
> 
> way, using a user defined type (EUSQLRESULT), to get errors reported to 
> the user, and this can cause the app to shut down or not (user-defined). 
>  
> I tend to use it for debugging and testing mostly, since it shuts down 
> and allows me to see where things went wrong.
> 
> I assume there must be a way to get at the error information in your
> library.  How do you recover from an error (i.e., what would you do if 
> foo1.txt didn't open, but you needed it to continue)?
> 
> Matt Lewis

My library is based on top of a lower level error library. The error 
library includes routines such as fatal_error() and error().
error() is a user definable error routine. By default it calls 
fatal_error(). Very much like you are describing Matt.

If I wanted to make sure that foo1.txt was successful before opening 
foo2..
I could set allow_error_trapping(ON) -- throw errors, but don't call 
them. This allows the exception to fall through the stack, to the next 
statement.
After opening foo1.txt, I can call trap_error(ERR_FOPEN). That would 
check the exception stack, and call the error handler immediately.
If I just want to check if there is a pending error, without actually 
calling the error handler, I can use catch_error(ERR_FOPEN)
if catch_error(ERR_FOPEN) then
  if some_special_condition then
    -- ignore this error
    errval = fetch_error(ERR_FOPEN) -- get the error data
    if drop_error(ERR_FOPEN) then end if
  else -- call the error handler 
    trap_error(ERR_FOPEN)
  end if
end if
If there is an error that I wish to simply ignore. I can just use 
drop_error().
fn1 = fopen("foo1.txt","rb")
if drop_error(ERR_FOPEN) then
  -- an error was encountered
end if 

Chris Bensler
Code is Alchemy

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu