"I don't think we'd want it to matter if errors are generated internally by Arc or Racket, so assuming that we do want to continue to raise errors in Arc with (err "foo") then I'm guessing we'd want to special case Racket exceptions and pass the exn-message string to the handler so that it would end up working the same way."
That actually makes me wonder if Arc should have access to 'raise as a separate function from 'err. After all, if we catch a Racket exception as a string, we lose information.
For all I know, losing that information isn't so bad. I almost always design code so it never throws exceptions that should be caught, so I don't know what information is useful to have in an exception. I've only encountered two places it makes sense to capture an exception:
- When the exception implements an escape continuation, in which case the necessary information is the unique identity of the catch point.
- When the program is something like a REPL or server that handles multiple commands and should typically recover from an error encountered in any one command. In this case, the necessary information is whether the error should be considered severe enough to take down or restart the particular command loop in progress. The usual approach to representing this information is a hierarchy of types such that, if you say exn:fail is okay, you implicitly say exn:fail:contract:divide-by-zero is okay. Is there a better approach?
---
By the way I don't think you do want to use call-with-exception-handler; if the handler returns[...]
"...the exn:break exception typically should not be caught..."
"Before any predicate or handler procedure is invoked, the continuation of the entire with-handlers expression is restored, but also parameterize-breaked to disable breaks."
Would it be better or worse to switch to 'with-handlers*, which doesn't disable breaks?