That seems fine, but the general approach the handin-server is taking seems wrong to me. If it wants an exception with a different message, it should just create that, rather than assuming that all exception structures are reasonable to modify.
Sam On Wed, May 4, 2016, 12:52 PM 'John Clements' via Racket Users < [email protected]> wrote: > Bump. > > Okay if I make a pull request to make ‘match’ exceptions transparent? I > see that all of the ones listed in 10.2.5 are transparent. > > John > > > On Apr 27, 2016, at 3:08 PM, John Clements <[email protected]> > wrote: > > > > > >> On Apr 27, 2016, at 3:01 PM, Sam Tobin-Hochstadt <[email protected]> > wrote: > >> > >> The exceptions raised by `match` are indeed not transparent. But I > >> don't understand why they need to be in order for the handin server to > >> handle them properly. > > > > (caveat: this is my reading of the code below) > > > > The handin server wants to add information to the exn-message part, in > order to indicate what handin test triggered the error. > > > > Doing this involves converting the exception to a vector, adding text to > the message part, and then reassembling and re-raising the error. The code > below therefore bails out when either “skipped?” turns out to be true or > when one or when struct->vector produces a vector with opaque fields. > > > > This doesn’t appear to be a problem for any of the other exceptions that > the handin server encounters (well, this is the first time I’ve seen this > problem, anyhow). > > > > I can hack the handin server to treat match exceptions specially, but > that definitely doesn’t seem like the right solution. > > > > John > > > > > > > > > > (define ((wrap-evaluator eval) expr) > > (define unknown "unknown") > > (define (reraise exn) > > (raise > > (let-values ([(struct-type skipped?) (struct-info exn)]) > > (if (and struct-type (not skipped?)) > > (let ([vals (cdr (vector->list (struct->vector exn unknown)))]) > > (if (memq unknown vals) > > exn > > (apply (struct-type-make-constructor struct-type) > > (format "while evaluating ~s:\n ~a" expr (car vals)) > > (cdr vals)))) > > exn)))) > > (with-handlers ([exn? reraise]) (eval expr))) > > > >> > >> Sam > >> > >> On Wed, Apr 27, 2016 at 5:58 PM, 'John Clements' via Racket Users > >> <[email protected]> wrote: > >>> > >>>> On Apr 22, 2016, at 1:47 PM, 'John Clements' via Racket Users < > [email protected]> wrote: > >>>> > >>>> Currently, the handin-server runs student expressions in an ‘eval’ > which intercepts errors and re-raises them with a message that includes the > failing expression. All good. > >>>> > >>>> However, it doesn’t catch all of them. Specifically, if the exception > contains any values that are opaque to struct->vector, it gives up and > re-raises the exception as-is. > >>>> > >>>> This turns out to cause a problem with “match” failures, which > include such values. This causes a problem for my students, because they’re > unable to see the text of the test cases that they failed. > >>>> > >>>> It’s easy enough to hack around this in my code by re-wording ‘match’ > failures in the same way that wrap-evaluator does. In general, though, it > seems like there’s no good reason that ‘match’ failures shouldn’t go into > the same bin as division by zero, applying a non-function, and all of the > other things that can go wrong during evaluation. > >>>> > >>>> In order to fix this, then, I’m trying to determine why this check > exists: what exceptions do you *not* want to re-word here? > >>> > >>> Okay, answering my own question and asking another: > >>> > >>> The fundamental reason for the existence of this logic is that the > handin-engine is trying to be careful, and modify exceptions that can > safely be reconstructed. If the “skipped” value is #t, or if one or more of > the values in the structure are opaque, this is impossible. At this point, > the handin engine just throws up its hands and decides to follow the > hippocratic oath, “first do no harm,” and let the exception continue as is. > >>> > >>> So, this leads to a different question: *why* is the match exception > different from all the other exceptions? Based on my reading of the > struct-info documentation, it appears that the ‘match’ form constructs > exceptions whose inspector is not the current one, or perhaps that it fails > to declare itself as transparent. > >>> > >>> My guess is that this is just an oversight, and that a ‘match’ > exception should be just as transparent as, say, a division by zero > exception. Here’s code that illustrates the difference: > >>> > >>> #lang racket > >>> > >>> (with-handlers ([exn:fail? > >>> (λ (exn) > >>> (struct-info exn))]) > >>> (/ 1 0)) > >>> > >>> (with-handlers ([exn:fail? > >>> (λ (exn) > >>> (struct-info exn))]) > >>> (match 13 > >>> ['a 4])) > >>> > >>> So, here’s my question: > >>> > >>> Is there a good reason for the difference between the `match` > exception (skipped is #t) and the division-by-zero exception (skipped is > #f) ? > >>> > >>> John > >>> > >>> > >>> > >>> > >>> -- > >>> 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 [email protected]. > >>> For more options, visit https://groups.google.com/d/optout. > > > > > > -- > 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 [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.

