Exception Handling

new topic     » topic index » view thread      » older message » newer message

I'm hoping to get some feedback on this library. Positive and negative 
criticism is appreciated.

I've written an error library and implemented what I 'think' is a 
exception handling system.

Sorry for the lack of documentation, but it's still in prototype.

Basically, I know nothing of exception handling other than my own 
theories and the other implementations that I have seen. I'd like to get 
some more insight as to the how and why.
Is this system sufficient? What are the main properties of an exception 
handling system?

My concept is to create exception handlers.
The handlers take an object parameter to be tested, check it, and make 
any changes to try and keep the data within the exception definition.
If the data is fit, the handler passes it back. Otherwise, an exception 
should be thrown from the handler so that an error is trigered.

There is no error stack. If an exception is thrown, an error occurs.
You can't catch errors, they are caught by the handlers. In oder to 
'catch' an error, you would have to implement the catch through the 
handler.

The example only demonstrates how the system works. It doesn't really 
demonstrate the flexibility that it can provide.

error.e is below the example

<EXAMPLE>
include error.e

-- display msg and wait for a keypress
global procedure wait(sequence msg)
   if length(msg) then
      puts(1,msg)
   end if
   while get_key()=-1 do end while
end procedure

-- if place = 0 round to nearest integer
-- if place > 0 then round to decimal place ( 1=0.1, 2=0.01 )
-- if place < 0 then round to tens place ( -1=10, -2=100 )
global function round(atom a, integer place)
 atom b
   b = floor(a)
   return b + ((a-b) >= (0.5*power(10,-place)))
end function

-- exception handler
-- if data > 10, then error
function over_10_handler(atom data)
   if data > 10 then
      throw_exception()
   end if   
   return round(data,0)
end function
constant err_over_10 = new_exception(routine_id("over_10_handler"),"%d 
is greater than 10")

wait(sprintf("%g   press any key\n",exception(0, err_over_10)))
wait(sprintf("%g   press any key\n",exception(3.7, err_over_10)))
wait(sprintf("%g   press any key\n",exception(9.8, err_over_10)))
wait(sprintf("%g   press any key\n",exception(13, err_over_10)))
<END EXAMPLE>


<ERROR.E>
include machine.e


-- GENERAL ERROR ROUTINES --

global procedure fatal_error(sequence msg)
   crash_message(msg)
   ? 1/0
end procedure

integer error_rID    error_rID=routine_id("fatal_error")
global procedure error(sequence msg)
   call_proc(error_rID,{msg})
end procedure

global procedure on_error(integer expr, sequence msg)
   if expr then error(msg) end if
end procedure

global procedure set_error_handler(integer err_rID)
   if err_rID <=0 then error_rID = routine_id("fatal_error") end if
   error_rID = err_rID
end procedure


-- EXCEPTION HANDLING ROUTINES --

-- {{exception_rIDs},{error_messages},{exception_data}}
constant ERR_rID=1,
         ERR_MSG=2
sequence stack    stack={{},{}}

-- this will be set to 1 if an exception handler is currently being 
processed
--   throw_exception() can only be called from an exception handler
integer err_check    err_check=0

global function new_exception(integer err_rID, sequence msg )
 integer f
   f = find(err_rID,stack[ERR_rID])
   if f then
      return f
   else      
      stack[ERR_rID] &=err_rID
      stack[ERR_MSG] &={ msg }
      return length(stack[ERR_rID])
   end if
end function

global function exception(object err_data, integer err_id)
   if stack[ERR_rID][err_id] < 0 then
      -- there is no exception handler routine
      -- crash and dump ex.err.
      error("Exception!: "&sprintf(stack[ERR_MSG][err_id],{err_data}))
   else
      err_check = 1
      err_data = call_func(stack[ERR_rID][err_id],{err_data})
      if not err_check then
         -- crash and dump ex.err.
         error("Exception! : 
"&sprintf(stack[ERR_MSG][err_id],{err_data}))
      end if      
   end if
   err_check = 0
   return err_data
end function

global procedure throw_exception()
   if not err_check then error("tried to throw and exception() outside 
of an exception handler") end if
   err_check=0
end procedure
<END ERROR.E>


What do you think?


Chris

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu