It is indeed a very flexible structure. Combined with that only explicit continue statements would avoid rethrowing, I think it would work well.
As for keywords, I think "try" and "onerror" fit best. Some examples:
Catch only I/O errors and report them on stderr:
try { do_stuff(); } onerror (Error err) if (err->is_io_error) { werror ("I/O error on %O: %s\n", err->file, err->description); continue; // Avoid rethrow. }
Catch and handle application specific errors, and log but rethrow I/O errors:
try { do_stuff(); } onerror (Error err) if (err->is_my_app_error) { handle_my_app_error (err); continue; // Avoid rethrow. } else { my_app_log ("Interrupted by error: %s\n", err->description); }
Clean up a cache no matter what happens:
int id = session_id++; try { session_cache[id] = SessionObj(); do_stuff(); } onerror () { m_delete (session_cache, id); // All errors are rethrown here. } m_delete (session_cache, id);
The last case, to always do some cleanup, is common and it shows code duplication. To avoid that I'd like a Java-style "finally" clause too:
int id = session_id++; try { session_cache[id] = SessionObj(); do_stuff(); } onerror (Error err) if (err->is_my_app_error) { handle_my_app_error (err); continue; // Avoid rethrow. } finally { // This is always executed no matter what happens above. m_delete (session_cache, id); // If the try block was interrupted by an error other than the // my_app type, it's rethrown here. }
/ Martin Stjernholm, Roxen IS
Previous text:
2003-10-01 22:33: Subject: Re: throw or return
| catch { | ...->accept(); | } | handle (Exception e) | { | if (e->system_error && e->errno==EAGAIN) | continue; | }
;-)
I think this structure is the best, if you want to switch you could always do that.
/ Mirar