Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

JobPhaseWhat is thrown intentionally?What is thrown accidentally?Where thrown?Detect where?Message templateExample errorExample messageMessage in 1.9
REPLRead / reading sourceIOEx, RuntimeEx, NumberFormatEx, IllegalArgumentEx, IllegalStateEx, UnsupportedOpExN/A

LispReader

wrapped in ReaderException in LispReader.read()

Catch during read in clojure.main/repl-readSyntax error reading at (LINE:COL). Cause: CAUSE:::5Syntax error reading at (1:1). Cause: Invalid token: :::5RuntimeException Invalid token: :::5 clojure.lang.Util.runtimeException (Util.java:221)
compileRead / reading sourceIOEx, RuntimeEx, NumberFormatEx, IllegalArgumentEx, IllegalStateEx, UnsupportedOpExN/A

LispReader

wrapped in ReaderException in LispReader.read()

ReaderException replaced with CompilerException in Compiler.compile()

Catch from LispReader.read() in Compiler.compile()

Syntax error reading source file at (SOURCE:LINE:COL). Cause: CAUSE

:::5 in .clj fileSyntax error reading source file at (foo.clj:2:0). Cause: Invalid token: :::5RuntimeException Invalid token: :::5 clojure.lang.Util.runtimeException (Util.java:221)
REPL | compilecompile / macroexpand (spec)ExceptionInfo w/spec keysN/ACompiler.checkSpecs()Catch from checkSpecs in Compiler.macroexpand1()

Syntax error macroexpanding MACRONAME at (SOURCE:LINE:COL):
PROBLEM-LIST

(let [x])

Syntax error macroexpanding clojure.core/let at (foo.clj:10:5):
In: [0] val: () fails spec: :clojure.core.specs.alpha/bindings at: [:args :bindings :init-expr] predicate: any?, Insufficient input

CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/let did not conform to spec:
In: [0] val: () fails spec: :clojure.core.specs.alpha/bindings at: [:args :bindings :init-expr] predicate: any?, Insufficient input
#:clojure.spec.alpha{:problems [{:path [:args :bindings :init-expr], :reason ""Insufficient input"", :pred clojure.core/any?, :val (), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings], :in [0]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x4b45dcb8 ""clojure.spec.alpha$regex_spec_impl$reify__2436@4b45dcb8""], :value ([x]), :args ([x])}, compiling:(foo.clj:10:5)

compilecompile / macroexpand (thrown by macro)thrown by core defmacro impls: IllegalArgEx, IllegalStateEx, Ex, ExInfo community is sameN/Ain macro implementations under Compiler.macroexpand()Catch during invocation of macro in Compiler.macroexpand1()Syntax error macroexpanding MACRONAME at (SOURCE:LINE:COL). Cause: CAUSE(cond 1)Syntax error macroexpanding clojure.core/cond at (foo.clj:10:5). Cause: cond requires an even number of formsIllegalArgumentException cond requires an even number of forms  clojure.core/cond (core.clj:600)
REPL | compilecompile / macroexpand (accidental throw in macro)N/Aeverything but intentional exs in prior rowin macro implementations under Compiler.macroexpand()"Unexpected error macroexpanding MACRONAME at (SOURCE:LINE:COL). Cause: EXCLASS CAUSE(defmulti 5 class)Unexpected error macroexpanding clojure.core/defmulti at (foo.clj:10:5). Cause: ClassCastException java.lang.Long cannot be cast to clojure.lang.IObjClassCastException java.lang.Long cannot be cast to clojure.lang.IObj  clojure.core/with-meta--5142 (core.clj:217)
REPL | compilecompileIOEx, RuntimeEx, NumberFormatEx, IllegalArgumentEx, IllegalStateEx, UnsupportedOpEx, ArityEx, ExceptionInfo, ReflectiveOperationExnot worrying about for now

Compiler expr parsers

wrapped in CompilerException in Compiler.compile()

Catch in analyze or eval in Compiler.compile1()Syntax error compiling EXPRNAME at (SOURCE:LINE:COL). Cause: CAUSE(def 5)Syntax error compiling def at (foo.clj:10:5). Cause: First argument to def must be a SymbolCompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(foo.clj:5:1)
REPL | runtimeevaluationany (except AssertionError or spec ExceptionInfo)don't differentiateany functionCatch in call to eval in clojure.main/replEvaluation error at STACKFN (STACKSRC:LINE). EXCLASS CAUSE

(/ 1 0)
(+ 1 :a)

Evaluation error at clojure.lang.Numbers.divide (Numbers.java:163). ArithmeticException Divide by zeroArithmeticException Divide by zero  clojure.lang.Numbers.divide (Numbers.java:163)
REPL | runtimeevaluation / spec instrumentExceptionInfo w/spec keysN/Ainstrumented spec"

Evaluation error at STACKFN (STACKSRC:LINE), did not conform to spec:
PROBLEM-LIST

(f :a)

Evaluation error at user/f (foo.clj:10), did not conform to spec:
In: [0] val: :a fails at: [:args :a] predicate: int?

ExceptionInfo Call to #'user/f did not conform to spec:
In: [0] val: :a fails at: [:args :a] predicate: int?
clojure.core/ex-info (core.clj:4739)

REPL | runtimeevaluation / assertion failure or pre/postAssertionErrorN/Aany function"Evaluation error at STACKFN (STACKSRC:LINE), CAUSE(assert false)Evaluation error at user/eval149 (NO_SOURCE_FILE:8), Assert failed: falseAssertionError Assert failed: false  user/eval149 (NO_SOURCE_FILE:8)
REPLprintN/Aallany functionCatch in call to print in clojure.main/replError printing return value at STACKFN (STACKSRC:LINE), encountered: EXCLASS CAUSE ?Error printing return value at some/thing (foo.clj:100). ArithmeticException Divide by 0 

 

(OLD, superceded by table above) How to format error messages in repl-caught and ex stacks in pst

Reader errors

If the error is encountered during reading, then the syntax of the code is invalid and the prime objective is to direct the user to the invalid code. The stack trace is probably of little use to a user as it will be buried in the LispReader.

  • Printed error
    • Format: RuntimeException MESSAGE, reading:(SOURCE,LINE,COLUMN)
    • Class and message come from wrapped exception
    • Source,line,col comes from ReaderException wrapper
    • Differences from current master:
      • Adds: "reading" similar to "compiling" to indicate phase
      • Adds: "SOURCE,LINE,COLUMN" info from ReaderException which is probably the most important info
      • Removes: top stack trace element like "clojure.lang.Util.runtimeException (Util.java:221)" - this is almost always irrelevant
  • pst
    • could omit wrapper ReaderException by default

Example (repl-caught before):

  • RuntimeException Invalid token: :::5 clojure.lang.Util.runtimeException (Util.java:221)

Proposed:

  • RuntimeException Invalid token: :::5, reading:(NO_SOURCE_PATH,1,1)

Macroexpansion error (non-spec)

If the error occurs during macroexpansion, then the macro code was executing and we want to point the user to the macro code. Possibly the most useful additional information to include would be the inputs to the macroexpansion.

  • Printed error
    • Format: CAUSE-CLASS MESSAGE (STACK-CLASS.STACK-METHOD:STACK-LINE)
    • Maybe we should say "macroexpanding" in here somewhere? Or wrap in CompilerException to grab invoking source info?
    • We could capture and report &form or &env?
    • Differences from master: none
  • pst
    • same

Example (repl-caught before):

Proposed (same, unless we indicate invocation location):

Macroexpansion error (spec)

Spec errors are CompilerExceptions wrapping an ExceptionInfo with well-known keys. Proposed to detect this and use the spec explain printer so expound etc can be used if desired.

  • Printed error
    • Format: CAUSE-CLASS MESSAGE, compiling:(STACK-CLASS.STACK-METHOD:STACK-LINE)

                    SPEC-PROBLEM...
    • What I really want to see here is what was the invocation that was occurring and which arg is invalid?
      • That is, the call being made is:  (let [x]) and violated the let spec. The info is all there but I have to mentally reassemble that "[0]" means the 1st element in the arg list and the 2nd element in the form. I am not looking for expound's 10 line explanation of this, but I think there is a lot of mental arithmetic here that we could help with.
    • Differences from master: 
      • Add: compiler location info (the offending source that invoked)
      • Remove: ex-data dump
      • Add: spec explain printer description
  • pst
    • same as before, but probably not relevant to user most of the time

Example (before):

  • ExceptionInfo: Call to clojure.core/let did not conform to spec:

    In: [0] val: () fails spec: :clojure.core.specs.alpha/bindings at: [:args :bindings :init-expr] predicate: any?, Insufficient input

    #:clojure.spec.alpha{:problems [{:path [:args :bindings :init-expr], :reason "Insufficient input", :pred clojure.core/any?, :val (), :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings], :in [0]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x25a6944c "clojure.spec.alpha$regex_spec_impl$reify__2436@25a6944c"], :value ([x]), :args ([x])}, compiling:(NO_SOURCE_PATH:4:1)

Proposed:

  • ExceptionInfo Call to clojure.core/let did not conform to spec., compiling:(NO_SOURCE_PATH:1:1)

    In: [0] val: () fails spec: :clojure.core.specs.alpha/bindings at: [:args :bindings :init-expr] predicate: any?, Insufficient input

An alternate proposal that used the function name, args etc:

  • ExceptionInfo Call to clojure.core/let did not conform to spec., compiling:(NO_SOURCE_PATH:1:1)

    Invocation: (let [x])

    In: [0] val: () fails spec: :clojure.core.specs.alpha/bindings at: [:args :bindings :init-expr] predicate: any?, Insufficient input

Compiler error

A compile error is a CompilerException wrapper (conveying location) around a cause chain (conveying the cause). The stack trace is typically irrelevant to the user.

  • Printed error
    • Format: CAUSE-CLASS MESSAGE, compiling(SOURCE,LINE,COLUMN)

    • Differences from master: 
      • Remove "CompilerException"
  • pst
    • could omit wrapper exception

Example (before):

  • CompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(NO_SOURCE_PATH:5:1)

Proposed:

  • java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(NO_SOURCE_PATH:5:1)

Evaluation error (non-spec)

An evaluation error can be anything, so is kind of the default case. It will not have a compiler exception wrapper. It may be an ExceptionInfo so need to consider how to print ex-data (which could be spec data).

  • Printed error:
    • Format: CAUSE-CLASS MESSAGE (STACK-CLASS.STACK-METHOD:STACK-LINE)

                   ex-data keys: [EX-DATA-KEYS]
    • Differences from master:
      • ex-data printing - either spec printer or keys
  • pst:
    • same

Example (before):

  • ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:163)

Proposed:

  • ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:163)

Evaluation error (spec)

TODO - mix of macro spec error and evaluation error

Background info

CompilerException

...