Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Java have setMessage in Exception/Throwable classes?

Tags:

java

exception

I am not able to understand why Java doesn't allow to change exception message of an exception of type Exception (or its superclass Throwable) once it has been created. It allows to change the stackTrace using setStackTrace but not the message.

The use case I have seems genuine to me and would appreciate some alternative.

Use case

I have a controller service X that calls let's say 10 other dependent services. To make debugging easy, if a dependent service throws some exception we want to surface some identifiers from service X to its upstream to identify the failed request easily. For this we have requestId which we create and set for each dependency.

Now to avoid duplication across all dependent services and simplify code, we can create a common interceptor that allows us to do some work before and after each call. Something like -

// do some work

requestId = getRequestId(); // create or somehow get requestId
dependentService.setRequestId(requestId);

try {
  dependentService.call();
}
catch (Exception e) {
  e.setMessage(e.getMessage() + ... + requestId);
  throw e;
}

//do some work

But Java doesn't allow us to set message. At the same time, we want to preserve the exception and its type (which could be any of the custom types defined by dependent services), so I don't want to do something like throw new Exception(e.getMessage() + ...)

like image 240
user11981729 Avatar asked Aug 27 '19 05:08

user11981729


People also ask

Do all exceptions in Java extend the throwable class?

All objects within the Java exception class hierarchy extend from the Throwable superclass. Only instances of Throwable (or an inherited subclass) are indirectly thrown by the Java Virtual Machine (JVM), or can be directly thrown via a throw statement.

Can throwable be cast to exception?

Throwable is a class which Exception – and consequently all subclasses thereof – subclasses. There's nothing stopping you from using instanceof on a Throwable .

Is throwable class is the root class of Java exception hierarchy?

The Throwable class, which is an immediate subclass of Object, is at the root of the exception hierarchy. Throwable has two immediate subclasses: Exception and Error.

How do you handle throwable exception in Java?

Throwing an exception is as simple as using the "throw" statement. You then specify the Exception object you wish to throw. Every Exception includes a message which is a human-readable error description. It can often be related to problems with user input, server, backend, etc.


3 Answers

It's not really what it's meant for, but you could attach another exception with addSuppressed:

} catch (Exception e) {
  e.addSuppressed(new ExtraInfoException(...));
  throw e;
}

where ... contains the extra info you want to include.

The advantage of this over adding to the exception message is that you can define your ExtraInfoException so that it has the info you want in fields, rather than having to parse it back out of the exception message.

With that said, a more idiomatic way to attach more exception info it would be:

} catch (Exception e) {
  throw new ExtraInfoException(e, ...);
}

which has exactly the same advantage of allowing you to return structured information, with the additional advantage that you can catch ExtraInfoException directly, rather than catching Exception and then hunting for the extra info reflectively.

like image 169
Andy Turner Avatar answered Oct 21 '22 20:10

Andy Turner


Why doesn't Java have setMessage in Exception/Throwable classes?

The answer to your question is that they (the library designers) did not think that changing a message on an exception was a useful thing to do.

To a large degree1, the designers have taken the view that they shouldn't design the APIs to directly support all possible use-cases ... including the obscure ones that almost nobody will encounter. Like your one2.

And in your case, there are other ways to achieve what you are trying to do; see the other answers.

I did a quick search of the Java bugs database to see if someone else had put in an RFE to request a setMessage method for Throwable or Exception. I couldn't find anything. If your requirement was even slightly common, there would probably be an RFE with an explanation of why it was declined.


1 - Obviously, there are exceptions to this, but that is beside the point.

2 - Obviously you would disagree that your use-case is obscure, but that that is also beside the point. The question is why they haven't implemented this, not whether they were wrong. (Asking / debating whether they were wrong is off-topic, because it is a matter of opinion.)

like image 37
Stephen C Avatar answered Oct 21 '22 20:10

Stephen C


Resetting a message it's some kind of rewriting the history. You have a catch block when you catch exception and handle them. If you need to throw an exception during the handling, it's a different problem and an exception should be different.

} catch (SomeException e) {
 // here we have SomeException and we want to handle it.
 // if we can't we throw a new one, because we have a problem with handling.
 // if the handling problem cause is SomeException we put it at the cause.
 throw new AnotherException("with some message", e);
}

And in the stacks trace we will see that we have AnotherException because of SomeException which gives us information about the root of problem.

like image 1
dehasi Avatar answered Oct 21 '22 20:10

dehasi