question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

make "catch (e) { ... }" catch Exception | AssertionError

See original GitHub issue

Exception and AssertionError are basically interchangeable and without distinction:

  • A reasonable application may catch either
  • Neither provides specific information that can be used for recovery
  • The decision to use one or the other is often one of syntactical convenience or habit: assert always throws AssertionError while code using throw often (but not always) throws Exceptions.

Currently, catch (e) catches Exceptions, but not AssertionErrors. Given the above, this behavior is of limited (perhaps no?) value and can even be surprising.

I propose that catch (e) be redefined to catch Exception | AssertionError.

While there are countless real world code examples to back the, uh…, assertion that Exception and AssertionError are not meaningfully different, the following contrived example shows how error handling code may be affected by the current behavior of catch.

The program has two bugs:

  1. The user input must be a positive integer (we’re passing the value to Iterable.step()), but the input is not validated
  2. Due to a language module limitation, 1 is not an acceptable input. Again, the input is not validated for this.
suppressWarnings("expressionTypeNothing")
shared void run() {
    process.write("Input step size: ");
    value step = Integer.parse(process.readLine() else "");
    if (!is Integer step) {
        print("Step must be an Integer");
    }
    else {
        value span = runtime.minIntegerValue..runtime.maxIntegerValue;
        try {
            print(span.by(step).take(10));
        }
        catch (e) {
            process.writeErrorLine(
                "Oops, that didn't work. Please report this bug!
                 ``e.message``");
            process.exit(1);
        }
    }
}

With user input “2”, the program works:

Input step size: 2
{ -9223372036854775808, -9223372036854775806, -9223372036854775804, -9223372036854775802, -9223372036854775800, -9223372036854775798, -9223372036854775796, -9223372036854775794, -9223372036854775792, -9223372036854775790 }

With user input “1”, the error handling code (catch (e) { ... }) is triggered (good):

Input step size: 1
Oops, that didn't work. Please report this bug!
offset from -9223372036854775808 to 9223372036854775807 cannot be represented as a 64 bit integer.

With user input “0”, the error handling code is not triggered, resulting in an ugly stack trace (bad):

Input step size: 0
Exception in thread "main" ceylon.language.AssertionError "Assertion failed: step size must be greater than zero
        violated step > 0
                left-hand expression is 0
                right-hand expression is 0"
        at ceylon.language.Span.by(Span.ceylon:156)
        at simple.run_.run(run.ceylon:11)
        at simple.run_.main(run.ceylon)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at ceylon.modules.api.runtime.SecurityActions.invokeRunInternal(SecurityActions.java:57)
        at ceylon.modules.api.runtime.SecurityActions.invokeRun(SecurityActions.java:48)
        at ceylon.modules.api.runtime.AbstractRuntime.invokeRun(AbstractRuntime.java:68)
        at ceylon.modules.api.runtime.AbstractRuntime.execute(AbstractRuntime.java:105)
        at ceylon.modules.api.runtime.AbstractRuntime.execute(AbstractRuntime.java:101)
        at ceylon.modules.Main.execute(Main.java:69)
        at ceylon.modules.Main.main(Main.java:42)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.jboss.modules.Module.run(Module.java:308)
        at org.jboss.modules.Main.main(Main.java:487)
        at ceylon.modules.bootstrap.CeylonRunTool.run(CeylonRunTool.java:367)
        at com.redhat.ceylon.common.tools.CeylonTool.run(CeylonTool.java:547)
        at com.redhat.ceylon.common.tools.CeylonTool.execute(CeylonTool.java:423)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.redhat.ceylon.launcher.Launcher.runInJava7Checked(Launcher.java:108)
        at com.redhat.ceylon.launcher.Launcher.run(Launcher.java:38)
        at com.redhat.ceylon.launcher.Launcher.run(Launcher.java:31)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.redhat.ceylon.launcher.Bootstrap.runVersion(Bootstrap.java:162)
        at com.redhat.ceylon.launcher.Bootstrap.runInternal(Bootstrap.java:117)
        at com.redhat.ceylon.launcher.Bootstrap.run(Bootstrap.java:93)
        at com.redhat.ceylon.launcher.Bootstrap.main(Bootstrap.java:85)

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:1
  • Comments:12 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
jvasileffcommented, Sep 3, 2017

we have to reach some sort of shared understanding of what AssertionErrors are even for

I think you’ll find the exact definition (exact distinction w/Exception) to be academic, a least with respect to this issue. Regardless, before trying to come up with a high level definition…

and in what circumstances one catches them

we can help ourselves by identifying which of the expressions in my comment above (and others, like assert(exists x) and Java NPEs) we might want to catch, and if any are excluded, why? It would be for catch (e) { ... } as in the example program, or perhaps a web application like:

try {
    processRequest();
}
catch (e) {
    log(e);
    serveBugReportAndTroubleshootingScreenToUser();
}

if there are other uses for catch (e) { ... } that are meaningfully different (would lead to different sets of exceptions we might want to catch), those should be described as well.

2reactions
gavinkingcommented, Sep 3, 2017

To even be able to make any progress at all in this discussion, we have to reach some sort of shared understanding of what AssertionErrors are even for, and in what circumstances one catches them.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to catch an assertion error in Java - Tutorialspoint
In order to catch the assertion error, we need to declare the assertion statement in the try block with the second expression being...
Read more >
Will an assertion error be caught by in a catch block for java ...
yes my assert code throws an exception. But i want to capture all errors such assertions or any other error by Exception class....
Read more >
Python | Assertion Error - GeeksforGeeks
AssertionError is inherited from Exception class, when this exception occurs and raises AssertionError there are two ways to handle, ...
Read more >
Java Exception Handling - AssertionError - Airbrake Blog
A deep dive into the Java AssertionError, including fully functional code showing how to use assertions within Java and how to avoid it....
Read more >
Make `AssertionError` extend `Exception` · Issue #7234 - GitHub
Never catch an Error without re-throwing an Error or ending the process. The very rare exception to this rule is when the potential...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found