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)))

Topic revision: r3 - 2010-01-11 - TerryVaskor
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback