racket / rackunit

Other
18 stars 34 forks source link

improve source locations in stacktraces #127

Closed rfindler closed 3 years ago

rfindler commented 3 years ago

When there is an exception while running check-equal?, eg with this program:

#lang racket
(require rackunit)

(define (f x) (car x))
(set! f f)

(check-equal? 1 (f #f))

then this PR improves the error reporting so we see the source location of the check-equal? in the stack. Before this pull request, we'd see something like this:

car: contract violation
  expected: pair?
  given: #f
  context...:
   /Users/robby/git/exp/plt/racket/share/pkgs/rackunit-lib/rackunit/private/check.rkt:121:16
   body of "/Users/robby/tmp.rkt"

and after it, the line that points to rackunit/private/check.rkt:121:16 points to the place where the check-equal? itself appears, /Users/robby/tmp.rkt:7:0 in this case.

rfindler commented 3 years ago

Here's a test case for this behavior. It returns #t with the PR in place and #f without.

#lang racket
(require rackunit)

(define (f x) (car x))
(set! f f)

(define exn
  (with-handlers ([exn:fail? values])
    (check-equal? 1 (f #f))))

(for/or ([frame (in-list
                 (continuation-mark-set->context
                  (exn-continuation-marks exn)))])
  (match frame
    [(cons _ (srcloc pth _ _ _ _))
     (equal? pth (syntax-source #'here))]
    [_ #f]))
jackfirth commented 3 years ago

Robby, this is fantastic.

rfindler commented 3 years ago

Thanks, @jackfirth !

Do you know the right place to put the test case?

jackfirth commented 3 years ago

@rfindler I think the pr directory would be a good spot, with #127 as the PR number.