Gauche Devlog

< Did you mean...? | 0.9.5, and what's next >

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.

  1. load-from-port and compile 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.
  2. The mixin condition, <load-condition-mixin> or <compile-error-mixin>, inherits <mixin-condition>.
  3. 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 method report-mixin-condition. In the above example, the ERROR: line is the main condition, and each While ... line is generated by report-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:

  1. Define a condition as a subclass of <mixin-condition>.
  2. 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))
    
  3. 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.

Tags: Condition, 0.9.5

Post a comment

Name: