Comments (7)
Hello, buko
Let us elaborate on this issue a bit more.
First, what is your scenario for logging exceptions? What is the logger you are using? And what version of Tascalate Concurrent are you using?
Second, yes, neither cause nor suppressed exceptions are initialized. All in all, what is a cause when there are multiple ones? And using addSuppresed
sounds to me as an API abuse. Probably I will add it but only if there are no other mechanism to fix the issue.
Third, I did some coding for dumping error info. To verify the functionality please try running TestMultitargetExceptionTraces (just copy sources -- it depends only on the Tascalate Concurrent lib).
Also, you can replace a line with
e.printStackTrace(); // line 11
with the following:
System.getLogger("any").log(Level.ERROR, "MY ERROR", e);
to verify that dumping errors works.
For me the output is:
net.tascalate.concurrent.MultitargetException
at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:21)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.err(TestMultitargetExceptionTraces.java:17)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.main(TestMultitargetExceptionTraces.java:10)
[2] -> java.lang.NoSuchMethodError: Data not found
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_2(TestMultitargetExceptionTraces.java:47)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_1(TestMultitargetExceptionTraces.java:43)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b(TestMultitargetExceptionTraces.java:39)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:24)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err(TestMultitargetExceptionTraces.java:17)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.main(TestMultitargetExceptionTraces.java:10)
[4] -> java.lang.IllegalArgumentException: Something wrong
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.a(TestMultitargetExceptionTraces.java:33)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:25)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err(TestMultitargetExceptionTraces.java:17)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.main(TestMultitargetExceptionTraces.java:10)
... Caused by: java.lang.NoSuchMethodError: Data not found
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_2(TestMultitargetExceptionTraces.java:47)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_1(TestMultitargetExceptionTraces.java:43)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b(TestMultitargetExceptionTraces.java:39)
... ... 4 more
[6] -> net.tascalate.concurrent.MultitargetException
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:26)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err(TestMultitargetExceptionTraces.java:17)
... at net.tascalate.concurrent.TestMultitargetExceptionTraces.main(TestMultitargetExceptionTraces.java:10)
... [0] -> java.lang.IllegalStateException: State is forbidden
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.c_2(TestMultitargetExceptionTraces.java:61)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.c_1(TestMultitargetExceptionTraces.java:57)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.c(TestMultitargetExceptionTraces.java:53)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:26)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err(TestMultitargetExceptionTraces.java:17)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.main(TestMultitargetExceptionTraces.java:10)
... [1] -> java.lang.NoSuchMethodError: Data not found
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_2(TestMultitargetExceptionTraces.java:47)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_1(TestMultitargetExceptionTraces.java:43)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.b(TestMultitargetExceptionTraces.java:39)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:26)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.err(TestMultitargetExceptionTraces.java:17)
... ... at net.tascalate.concurrent.TestMultitargetExceptionTraces.main(TestMultitargetExceptionTraces.java:10)
If your logging framework doesn't support dumping stack trace, then it's pretty easy to dump MultitargetException to StringWritter:
// e is a MultitargetException here
java.io.StringWriter w = new java.io.StringWriter();
e.printStackTrace(new java.io.PrintWriter(w));
System.out.println(w.toString());
Waiting for your reply.
from tascalate-concurrent.
We're using the latest version from maven.
It really is important to initialize the cause and the suppressed exceptions for MultitargetException. We have automated monitoring systems that are inspecting cause and suppressed exceptions and looking for specific types. It seems very strange that these systems break because MultitargetException, even though it clearly has a cause, doesn't expose that to the world. It seems to me a good idea to always pick the first exception as the cause and add the rest as suppressed.
Overriding printStackTrace() is a good idea but I would be concerned that it's not possible to retrieve the actual underlying Exception objects from MultitargetException without writing special code specifically for MultitargetException. We actually have code that knows how to work with the standard APIs and generate detailed error reports.
Also overriding printStackTrace() does not solve the problem. The MultitargetException itself gets wrapped in another exception. When the logging system eventually calls printStackTrace() on the root exception (which may wrap another exception which may wrap another exception which may eventually wrap MultitargetException) it is the standard prinstStackTrace() code that gets executed, not MultitargetException's printStackTrace(). The standard printStackTrace() knows how to deal with causes and suppressed exception so that can be highlighted but it doesn't know how to deal with MultitargetException. This is what I mean when I said MultitargetException swallows exceptions, it doesn't actually expose their existence through the standard APIs that everything else depends on.
from tascalate-concurrent.
Hello,
Now I see your point. When I dump new IOException("Invalid user input", new MultitargetException(excepionsList))
I see truncated output, while by default Throwable.printStackTrace
inspects causes and suppressedExceptions.
I did a rough test and add all exceptions as suppressed, here is an output:
SEVERE: MY ERROR
java.io.IOException: Invalid user input
at net.tascalate.concurrent.TestMultitargetExceptionTraces.outer(TestMultitargetExceptionTraces.java:18)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.main(TestMultitargetExceptionTraces.java:11)
Caused by: net.tascalate.concurrent.MultitargetException
at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:26)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.err(TestMultitargetExceptionTraces.java:22)
... 1 more
Suppressed: java.lang.NoSuchMethodError: Data not found
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_2(TestMultitargetExceptionTraces.java:52)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_1(TestMultitargetExceptionTraces.java:48)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b(TestMultitargetExceptionTraces.java:44)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:29)
... 2 more
Suppressed: java.lang.IllegalArgumentException: Something wrong
at net.tascalate.concurrent.TestMultitargetExceptionTraces.a(TestMultitargetExceptionTraces.java:38)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:30)
... 2 more
Caused by: java.lang.NoSuchMethodError: Data not found
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_2(TestMultitargetExceptionTraces.java:52)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_1(TestMultitargetExceptionTraces.java:48)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b(TestMultitargetExceptionTraces.java:44)
... 4 more
Suppressed: net.tascalate.concurrent.MultitargetException
at net.tascalate.concurrent.TestMultitargetExceptionTraces.err_1(TestMultitargetExceptionTraces.java:31)
... 2 more
Suppressed: java.lang.IllegalStateException: State is forbidden
at net.tascalate.concurrent.TestMultitargetExceptionTraces.c_2(TestMultitargetExceptionTraces.java:66)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.c_1(TestMultitargetExceptionTraces.java:62)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.c(TestMultitargetExceptionTraces.java:58)
... 3 more
Suppressed: java.lang.NoSuchMethodError: Data not found
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_2(TestMultitargetExceptionTraces.java:52)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b_1(TestMultitargetExceptionTraces.java:48)
at net.tascalate.concurrent.TestMultitargetExceptionTraces.b(TestMultitargetExceptionTraces.java:44)
... 3 more
Is it enough? I see no reason to add arbitrary cause. Or I can: (A) add a cause when there is a single exception and do not add suppressed at all in this case OR (B) add all exceptions as suppressed when there are multiple.
Is it ok for you?
from tascalate-concurrent.
Adding all the exceptions as suppressed works fine. That kind of output is exactly what we're looking for and what we hope to find when we examine the cause/supressed exceptions.
I also think it would be a good idea for MultitargetException to override Throwable.getMessage(). Right now MultitargetException doesn't override this method and provide any summary of what happened. It would be good if MultitargetException could print a message summarizing what happened, even if the exception stack trace wasn't available. This could look like:
public String getMessage() {
List<Throwable> listCopy = getErrors();
StringBuilder sb = new StringBuilder("A MultitargetException has " + listCopy.size() + " exceptions. They are:\n");
int lcv = 1;
for (Throwable th : listCopy) {
sb.append(lcv++ + ". " + th.getClass().getName() + ((th.getMessage() != null) ? ": " + th.getMessage() : "" ) + "\n");
}
return sb.toString();
}
from tascalate-concurrent.
I will not overwrite getMessage
-- it's used for dumping exceptions in Trowable.printStackTrace
hence the output would contain a lot of duplicated (and, therefore, confusing) data. Instead, I'll try to override toString()
-- should be enough. All the rest will be available via standard Trowable.printStackTrace
functionality that dumps full info of regular cause
and suppressed
.
from tascalate-concurrent.
Indeed, I have to overwrite getMessage
to include brief info about "nested" exceptions and toString
to avoid using getMessage
(infinite recurion otherwise).
Please get sources and check locally, the next build will be released within 2-5 days.
from tascalate-concurrent.
I take back my words about API abuse with addSuppressed
.
java.net.URLClassLoader
, method close
-- there is some kind of "batch processing", and exceptions are handled exactly this way -- first one is a cause, others are suppressed. So this practice is somewhat normal.
from tascalate-concurrent.
Related Issues (20)
- Issues with Callbacks HOT 11
- OnTimeout not working when computing intensive task HOT 5
- orTime and submit combination HOT 5
- How to wrap a Promise into Promise.retry HOT 5
- Typo in DelayPolicy#withMinDelay HOT 1
- Feature enhancement on cancel HOT 2
- A FutureLocal.java would be nice(like ThreadLocal.java but more) HOT 1
- Include class names in the documentation when highlighting a method
- Unexpected cancellation behavior HOT 6
- Promise.onTimeout does not cancel the async call in original CompletableTask.supplyAsync? HOT 8
- Promises#all(CompletionStage<? extends T>...) cancellation does not seem to work correctly HOT 5
- The cancel is not working on the async chain HOT 3
- Wait for Interrupted of CompletableTask.cancel HOT 4
- onTimeout behaviour confusing after 0.8.4 HOT 2
- Optimized Same Executor Runs HOT 1
- Mapped promise can't be interrupted HOT 1
- Exceptions in thenCompose() will not propagate HOT 3
- Promises.all - List type argument HOT 3
- whenCompleteAsync adds the failure exception as a suppressed exception to itself HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tascalate-concurrent.