2016/08/10
Better error reporting during loading/compiling
As the release of 0.9.5 nears, we'd like to post some miscellaneous topics about the features introduced in 0.9.5 so that it can be referred back.
If you've been using HEAD, you might have noticed slightly different error message when you hit something wrong during loading or compiling. This is how it looks like (I added random thingy in rfc.uri just to trigger an error.):
gosh> (use rfc.http) *** ERROR: unbound variable: error! While loading "../lib/rfc/uri.scm" at line 344 While compiling "../lib/rfc/http.scm" at line 46: (define-module rfc.http (use srfi-11) (use srfi-13) (use rfc.822) (use rfc.uri) (use rfc.base64) (use ... While loading "../lib/rfc/http.scm" at line 76 While compiling "(standard input)" at line 1: (use rfc.http) Stack Trace: _______________________________________ 0 (eval expr env) at "../lib/gauche/interactive.scm":282
It shows that Gauche just evaluated the form typed in to REPL, which is
(use rfc.http)
, which caused to load ../lib/rfc/http.scm
,
which triggers to compile (define-module ...)
,
which in turn loads ../lib/rfc/uri.scm
, which had a problem.
We implement this feature using compound conditions.
load-from-port
andcompile
catches an error, and re-raise a compound condition with the original condition plus a mixin condition that holds the context of loading or compilation.- The mixin condition,
<load-condition-mixin>
or<compile-error-mixin>
, inherits<mixin-condition>
. - The standard error reporting procedure,
report-error
, prints the information of thrown condition before the stack trace. If the thrown condition consists of a main condition (e.g.<error>
and several mixin conditions, it first shows the main condition, then lists the mixin condition info using a methodreport-mixin-condition
. In the above example, theERROR:
line is the main condition, and eachWhile ...
line is generated byreport-mixin-condition
method.
This mechanism is open to the user---if you want to add some context information to the error, all you need to do is:
- Define a condition as a subclass of
<mixin-condition>
. - Capture the error while you're doing stuff and re-raise
a condition with additional mixin condition.
(guard (e [(condition? e) (raise ($ make-compound-condition e $ make <my-mixin-condition> :key val ...))]) (do-your-stuff))
- Define
report-mixin-condition
specialized to your mixin condition.(define-method report-mixin-condition ((e <my-mixin-condition>) port) ...)
You can see how <load-mixin-condition>
and <compile-error-mixin>
condition are handled in src/libomega.scm
.
Post a comment