[racket] how do you raise a runtime error with source location information?

From: Danny Yoo (dyoo at cs.wpi.edu)
Date: Tue Jun 21 12:31:05 EDT 2011

On Mon, Jun 20, 2011 at 11:38 PM, Grant Rettke <grettke at acm.org> wrote:
> On Mon, Jun 20, 2011 at 10:00 PM, Robby Findler
> <robby at eecs.northwestern.edu> wrote:
>> I don't know if there is one already that is a good match for what you
>> want, but you can always use prop:exn:srclocs to make a new one.
>
> Feels like "Adding New Exception Types" oughta have its own section
> immediately following "9.2.4    Built-in Exception Types", starting with
> the srclocs info.


I'd like to contribute the following example to the docs, right next
to the section about that srcloc property.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket

;; We create a structure that supports the prop:exn:srcloc protocol:
;; It carries with it the location of the syntax that is guilty.
(define-struct (exn:fail:he-who-shall-not-be-named exn:fail) (a-srcloc)
  #:property prop:exn:srclocs (lambda (a-struct)
                                (match a-struct
                                  [(struct exn:fail:he-who-shall-not-be-named
                                     (msg marks a-srcloc))
                                   (list a-srcloc)])))

;; We can play with this by creating a form that looks at identifiers, and
;; only flags specific ones.
(define-syntax (skeeterize stx)
  (syntax-case stx ()
    [(_ expr)
     (cond
       [(and (identifier? #'expr)
             (eq? (syntax-e #'expr) 'voldemort))
        (quasisyntax/loc stx
          (raise (make-exn:fail:he-who-shall-not-be-named
                  "oh dear don't say his name"
                  (current-continuation-marks)
                  (srcloc '#,(syntax-source #'expr)
                          '#,(syntax-line #'expr)
                          '#,(syntax-column #'expr)
                          '#,(syntax-position #'expr)
                          '#,(syntax-span #'expr)))))]
       [else
        ;; Otherwise, leave the expression alone.
        #'expr])]))

(define (f x)
  (* (skeeterize x) x))

(define (g voldemort)
  (* (skeeterize voldemort) voldemort))


;; Examples:
(f 7)
(g 7)  ;; The error should highlight the use of the one-who-shall-not-be-named
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



Posted on the users mailing list.