Why does the stacktrace stops short of the error?

I've created a minimal example for a nasty error I had:

#lang racket

(require "foo.rkt")

(module+ main
  (run))

(define (run)
  (error-fun 7))

and foo.rkt:

#lang racket

(provide error-fun)

(struct foo (num))

(define (error-fun foo)
  (foo 8))

When running this with racket main.rkt I get this error:

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: 7
  context...:
   body of (submod "/home/ingmar/projects/racket-stacktrace/main.rkt" main)

Mind, I know what the error is: because error-fun has a parameter named foo, the line below can't create a struct of type foo (which was the intention). I would've to rename either the struct or the parameter.

The problem I have is that the error message is not in the least helpful to find the error. Mind, this is a minimal example; I've had a similar error in a much larger codebase.

Specifically:

  • The file with the error isn't mentioned at all (foo.rkt).
  • The function with the error isn't mentioned either (error-fun).
  • The offending line in the code isn't quoted nor the line number is displayed.

My question is, is there a better way of finding an error like this? Is there a coding style I should follow to get better error messages?

Someone else may be able to explain the lower level details as to why this is, but what you want is to compile your code with the errortrace module. See:

So running racket -l errortrace -t main.rkt will show the line triggering the error:

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: 7
  errortrace...:
   /home/jonathan/foo.rkt:8:2: (foo 8)
  context...:
   body of (submod "/home/jonathan/main.rkt" main)

Drracket and emacs(with racket-mode) both have built-in methods to run your code with errortrace, which makes it easy if you use those.

1 Like