Providing code to capture and report exceptions
The following module provides a single function whose purpose is to capture and report exceptions. This should be used for a test that is expected to raise an exception, so it can be verified that an exception is in fact raised and that it contains the expected content.
Sample code 1 — No macros
The module code is:
#lang scheme
(provide capture-and-report-if-exception-was-raised)
(define (error-call fn . args)
(with-handlers ((exn:fail? (lambda (exn) exn)))
(apply fn args)))
(define (capture-and-report-if-exception-was-raised fn . args)
(local ((define e (apply error-call fn args)))
(cond
[(exn? e) (exn-message e)]
[else "No exception raised"])))
#|
; Examples
(capture-and-report-if-exception-was-raised / 4 3) => "No exception raised"
(capture-and-report-if-exception-was-raised / 5 0) => "/: division by zero"
|#
As an example, a
test.ss
file in
BitterSuite may contain the following test to see if the
/
function works as expected:
(desc "(/ 4 0) reports the correct error")
(result (capture-and-report-if-exception-was-raised / 4 0))
(expected "/: division by zero")
Sample Code 2 — With macros
It may feel unnatural to pass the function followed by its parameters as the parameters of the exception reporter. As well, a function cannot be passed as a parameter in Beginning Student under normal circumstances, preventing this from being used in the Beginner languages.
This can instead be written to take an expression that will later be evaluated with the use of macros (along with some other simplification). The code could then become:
#lang scheme/base
(provide capture-and-report-if-exception-was-raised)
(define-syntax capture-and-report-if-exception-was-raised
(syntax-rules ()
((_ expr)
(with-handlers ((exn:fail? (lambda (exn) (exn-message exn))))
expr
"No exception raised"))))
#|
; Examples
(capture-and-report-if-exception-was-raised (/ 4 3)) ;=> "No exception raised"
(capture-and-report-if-exception-was-raised (/ 5 0)) ;=> "/: division by zero"
|#
The result expression in
test.ss
from sample code 1 would change to
(result (capture-and-report-if-exception-was-raised (/ 4 0)))