1

I have the following code

try {
    ....
} catch (Exception e) {
    log.error(String.format(SOME_CUSTOM_VARIABLE, e);
    throw e;
}

I want the exception to get the string SOME_CUSTOM_STRING_WITH_VARIABLES.
So what I want to do is

try {
    ....
} catch (Exception e) {
    log.error(String.format(SOME_CUSTOM_VARIABLE, e);
    throw new Exception(SOME_CUSTOM_VARIABLE, e);
}

But this forces me to add "throws Exception" to the method signature.
This method threw an exception anyhow. Why do I have to change the signature?

How do I replace a basic exception with another one?

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
Bick
  • 17,833
  • 52
  • 146
  • 251

5 Answers5

0

Because throwing an exception means creating your own Exception that your method throws so you need to declare that the method throws it so that users of the method know to catch it. Like how you had to surround whatever it was in a try-catch in the first place. If it wasn't enforced that you declare that your method throws then Exceptions could just go missing.

Ross Drew
  • 8,163
  • 2
  • 41
  • 53
0

In Java you have checked exceptions - these must be declared by the throwing method - and unchecked, which need not be. (And then there are Error's, but let's leave them aside for now).

Not going into the details of which exception strategy to use, basically you can throw any exception that is a or extends from RuntimeException without having to declare it on your method. Eg. you could

void myMethod() { // no 'throws' declaration
    try {
        ...
    } catch (Exception e) {
        throw new RuntimeException( SOME_CUSTOM_VARIABLE , e );
    }
}

I'll recommend this SO thread and this blog post for a good discussion on the topic.

On the question of replacing an exception with another in the throws clause: I understand that your method already threw some exception which isn't specifically java.lang.Exception. In that case, you're mostly out of luck - you can only "replace" the thrown exception with the same or a subclassed one, otherwise you'll have to edit/add to the throws clause.

Cheers,

Community
  • 1
  • 1
Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
0

If you don't want to change the method signature, you could create a custom RuntimeException and throw it.

Be aware of consequences though :

  • If this custom RuntimeException is not properly catch in upper classes, it could crash the entire program.
  • It's more like a workaround, when a RuntimeException is thrown, the program should not recover from the exception. Runtime exceptions represent problems that are the result of a programming problem.

Some information about this : https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

ToYonos
  • 16,469
  • 2
  • 54
  • 70
0

But this forces me to add "throws Exception" to the method signature.This method threw an exception anyhow. Why do I have to change the signature?

It depends, if you are throwing checked exception then java compiler will force you to handle it i.e. you need to include it in method signature or handle it in the method body.
BUT if you throw unchecked exception than there is no need to modify the method signature

sol4me
  • 15,233
  • 5
  • 34
  • 34
0

I strongly recommend you don't solve this by throwing a RuntimeException. Those are strictly the preserve of the JVM and it would be dreadful style to use one just to avoid declaring a throw clause.

The name and purpose of the Java exceptions is (IMHO) confused. You should stick to the idea that things subclassed from Exception need handlers and things derived from Error don't. Ignore the rule-breaker RuntimeException and complain bitterly to your mates down the pub and random people on stackoverflow.com that it ought to just be called RuntimeError and sub-class Error (for f**ks sake).

If you really have a condition where a method has a throws clause declaring an Exception but you have good reason to now throw it up then I suggest you sub-class Error to either UnexpectedExceptionError or UnhandledExceptionError.

Use the first if the Exception is 'not supposed to be possible - such as an abstract I/O method that you know is backed by (say) a string in memory and can't really throw IOException despite the interface declaration.

Use the second if throwing the Exception would break the signature of some method you're implementing/overriding that can't be modified to advertise the potential Exception.

As a third-way it's natural for exceptions to propagate to the run() method of Runnable. In those cases I recommend passing the Exception to some overseer process as a kind of suicide note because whatever you throw out of run() will get ignored anyway and you probably want do something to recognize complete failure of a Thread!

PS: If you're doing this because you're lazy and don't want to handle exceptions properly, may you be cursed to maintain code written by someone with the same attitude :)

Persixty
  • 8,165
  • 2
  • 13
  • 35