At Wed, 26 Jul 2017 14:44:05 -0700 (PDT), Thomas Dickerson wrote: > Looking at this code specifically: > > | mz_jmp_buf * volatile save, fresh; > | save = scheme_current_thread->error_buf; > | scheme_current_thread->error_buf = &fresh; > | > | if (scheme_setjmp(scheme_error_buf)) { > | /* There was an error or continuation invocation */ > | if (scheme_jumping_to_continuation) { > | /* It was a continuation jump */ > | scheme_longjmp(*save, 1); > | > | /* To block the jump, instead: scheme_clear_escape(); */ > | } else { > | /* It was a primitive error escape */ > | } > | } else { > | scheme_eval_string("x", scheme_env); > | } > | scheme_current_thread->error_buf = save; > > I have questions about a few things: > (a) Why does the example check for an error *before* calling > `scheme_eval_string`, rather than afterward? Is this just something weird > with > setjmp/longjmp?
Yes, that's how setjmp() and longjmp() work. The initial call to setjmp() always returns 0, etc. > (b) How do I handle the "primitive error escape" branch, assuming I > want to print a useful error message, and continue executing > gracefully? It looks like `scheme_clear_escape` may be useful for > preventing the exception from propagating, but I'm not sure about > that from the documentation (or how I'd be able to capture the error > message from the exception). That branch corresponds to `abort-current-continuation`. If it's due to an exception, then the exception was already printed and (probably) the default error escape handler called `abort-current-continuation`. Catching the value raised as an exception is not practical to do in C. It's better to wrap up the work like `scheme_eval_string("x", scheme_env)` in a thunk and call a Racket-implemented wrapper. Section 9.1 in "Inside Racket" shows one way to do that. > (c) Is this style of error handling only necessary around blocks that > are evaluating actual Racket code (via, e.g., `scheme_eval_string` or > `scheme_dynamic_require`)? What about the > `scheme_register_embedded_load` and `scheme_embedded_load` pair at > the bottom of `declare_modules`? I ran my binary through the Unix > `strings` command and the embedded data looks an awful lot like > expanded S-expressions in plain text. Additionally, at what level of > granularity should I structure the error handling? Does it need to be > for *every* evaluation, individually? Or could I surround a whole > block of evaluations with the same error handling code? Declaring (as opposed to instantiating) a compiled module will normally not raise an exception. Probably it's possible to construct a set of embedded modules where there will be a declare-time error due to conflicting or missing declarations, but I don't see how to make that happen only sometimes. The escape-catching pattern is needed anywhere that you don't want to just exit/crash. You can certainly call multiple `scheme_...` functions within a single escape-handling block, including multiple calls to `scheme_eval_string`. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.