How can I set the message on an exception in Java? - java

I want to set a custom exception message. However, I'm unsure of how to do this. Will I need to create a custom exception class or is there an easier way of doing this?

Most standard exception classes provide a constructor that takes a mesage, for example:
public UnsupportedOperationException(String message) {
super(message);
}
The above class simply calls its parent's constructor, which calls its parent's constructor, and so on, ultimately culminating in:
public Throwable(String message) {
...
}
If you create your own exception class, I think it's a good idea to following this convention.

You can only set the message at the creation of the exception. Here is an example if you want to set it after the creation.
public class BusinessException extends RuntimeException{
private Collection<String> messages;
public BusinessException(String msg){
super(msg);
}
public BusinessException(String msg, Exception cause){
super(msg, cause);
}
public BusinessException(Collection<String> messages){
super();
this.messages= messages;
}
public BusinessException (Collection<String> messages, Exception cause){
super(cause);
this.messages= messages;
}
#Override
public String getMessage(){
String msg;
if(this.messages!=null && !this.messages.isEmpty()){
msg="[";
for(String message : this.messages){
msg+=message+",";
}
msg= StringUtils.removeEnd(msg, ",")+"]";
}else msg= super.getMessage();
return msg;
}
}

Well, if the API offers an exception that suits your needs (IllegalArgumentException for example), just use it and pass your message in the constructor.

The best approach is to wrap the exception.
try {
my code that throws E;
} catch (final E e) {
throw new MyE("my message", e);
}

The Exception class (its parent, actually - Throwable) takes a message as an argument in its constructor:
throw new Exception("message") or Exception("message", innerException);

The root Exception class accepts a String custom message, as do (as far as I can tell) all of derivative classes.
So: no, you don't need to create a custom class. One of the existing exceptions probably covers your case (read their descriptions to find out which). If none of those are really satisfactory, then you can create an extension of Exception (or RuntimeException, etc.) and maintain the custom message constructor.

Try this code:
try{
throw new Exception("Test String");
}
catch(Exception ex){
System.out.println(ex.getMessage());
}

Another variant
public class MyCustomExceptionWithoutMessageInConstructor extends IllegalArgumentException {
private static final String ERROR_MESSAGE = "terrible error";
public MyCustomExceptionWithoutMessageInConstructor() {
super(ERROR_MESSAGE);
}
}

Related

Any way to pass second parameter in exceptionHandler?

Have a service method which can throw an exception
if (NOT_FOUND) {
throw new ResourceNotFoundException("Resource not found");
}
And ControllerAdvice with exceptionHandler
#ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity handleResourceNotFound(Exception ex) {
return new ResponseEntity("your-error-message");
}
So i need to pass another String as param and access it form exceptionHanlder:
if (NOT_FOUND) {
String param2 = "param2";
throw new ResourceNotFoundException("Recource not found", param2);
}
#ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Problem> handleResourceNotFound(Exception ex) {
doomething(param2);
return new ResponseEntity({your-error-message});
}
Is there any way to do it?
Yes, as Abra said, you can create your own exception that inherits from ResourceNotFoundException, and add the other parameter there. Then in the exception handler you can get it from the exception:
This could be the class
public class CustomException extends ResourceNotFoundException {
private String otherParam;
public CustomException(String message, String otherParam) {
super(message);
this.otherParam = otherParam
{
public getOtherParam() {
return otherParam;
}
}
Then you throw it
throw new CustomException("Recource not found", param2);
Then in exception handler you can get the second param
#ExceptionHandler(CustomException.class)
public ResponseEntity<Problem> handleResourceNotFound(CustomException ex) {
doomething(ex.getOtherParam());
return new ResponseEntity(ex.getMessage());
}
i refer to the error handle tutorial (chapter 6.3) , where you see an proper usage of the Exception Handler as you did in your code snippet.
there is an interesing aspect of your approach:
Of course, we'll use the global exception handling mechanism that we discussed earlier to handle the AccessDeniedException as well:
so the purpose of your Exception Handler is to handle Exceptions of a vast variety of exceptions: global exception handling. You would not know where the exception was thrown. Therefor it makes no sense to add additional logic to your Exception handler on the Handler side.
rather than adding a backpack to the handler you should take the action on the point of existing. that would take a small archituetur change and handle there:
if (NOT_FOUND) {
String param2 = "param2";
doomething(param2);
throw new ResourceNotFoundException("Recource not found");
}
clean code - separation of concerns
if it was a general aspect of exception handling, you would have the general informatiaon already in your hands
if it is a specific aspect, then it should be handled where it happens!
Just update your advice:
#ExceptionHandler(ResourceNotFoundException.class)
// public ResponseEntity handleResourceNotFound(Exception ex) {
public ResponseEntity handleResourceNotFound(ResourceNotFoundException ex) {
// ex contains all parameters that you need
return new ResponseEntity("your-error-message");
}

Ability to throw an exception type provided by the caller

I have a generic function which does something and, in case of failure, it should throw a specific exception.
To simplify you can imagine it as such:
public static <E extends Exception> void doSomething(Class<E> exceptionClass) throws E {
try {
//Do stuff
} catch (Exception e) {
String message = "...";
//-> here I want to throw a new exception of type E with the message I built above and the caught exception as cause
}
}
In order to do that, what I can think about is to build a new E by reflection and throw an unchecked exception if any of the exceptions that can be thrown during reflection is actually thrown:
public static <E extends Exception> buildException(Class<E> exceptionClass, String msg, Throwable cause) {
try {
return exceptionClass.getDeclaredConstructor(String.class, Throwable.class).newInstance(msg, cause);
} catch (NoSuchMethodException ... e) {
//Catch everything that can be thrown
throw new RuntimeException(e);
}
}
... and then call it simply throw buildException(exceptionClass, message, e) inside the main function.
However I don't like too much this solution because I need to get the class in parameter from the caller (while they are already inferring me the type via E) and I may as well have to throw a Runtime exception if my reflection operation fails (all E extends Exception so the constructor I look for should always be there, but we never know if the caller doesn't customize the exception too much...)
Although the drawbacks, I can't get anything better into my mind.
Does anyone have some better design ideas for this?
Note: about the need. I have several classes which perform the same operation (the "do stuff") but that need to throw a specific exception (class 1 throws exception 1, class 2 throws exception 2 etc.) which wraps any possible exception thrown while performing the "do stuff" operation. Of course I may move the catch on caller side but that would make a lot of code duplication for the exact same operation.
Instead of passing the class and let the called method handle the exception creation you could let the calling method handle it instead. This is possible by accepting a function:
public static <E extends Exception> void doSomething(Function<String, E> exceptionFunction) throws E {
try {
//Do stuff
} catch (Exception e) {
String message = "...";
throw exceptionFunction.apply(message);
}
}
This function would expect a String, your message, and will then return an instance of the exception to be thrown. As you can see, you can trigger the function by using exceptionFunction.apply(message).
You can also use e to add the "cause" stacktrace:
public static <E extends Exception> void doSomething(Function<String, E> exceptionFunction) throws E {
try {
//Do stuff
} catch (Exception e) {
String message = "...";
var exception = exceptionFunction.apply(message);
exception.initCause(e);
throw exception;
}
}
The call of the doSomething method would then look like this:
doSomething((s) -> new MyException());
or if you prefer method references, like this:
doSomething(MyException::new);
(mind that MyException would need a constructor with a String parameter)

am developing API in java so i need to handle exceptions my customException class extends which class either Exception or Runtime Exception

my class extends which class please give me suggestion
public class MyException extends Exception {
public MyException (Exception ex) {
super(ex);
}
public MyException (String message) {
super(message);
}
public MyException (Exception ex,String moduleKey) {
super(ex, moduleKey);
}
public MyException (Exception ex, String moduleKey, String message) {
super(ex, moduleKey, message);
}
!-- end snippet -->
It all depends on whether you want to force API users to try/catch (or declare throws) every time your exception might be raised, or you want them to crash the application just like NullPointerException does.
The first kind should be used whenever the exception is to be expected - like IOExceptions for instance. RuntimeExceptions usually suggest that something weird happend during (as the name suggests) runtime - a weird language behaviour, unexpected thread clash and so on. Usually you want to use the regular Exception though.

JUnit testing custom exception [duplicate]

This question already has an answer here:
Junit Test Case for exception [closed]
(1 answer)
Closed 7 years ago.
I'm using JUnit and not quite sure how to test custom exception class. I have created,
public class CustomException extends Exception {
//#param message is the exception message
public CustomException(final String message) {
super(message);
}
//#param message is the exception message
//#param cause is the cause of the original exception
public CustomException(final String message, final Throwable cause) {
super(message, cause);
}
}
main class would have many try catch such as:
catch (ParseException e) {
throw new CustomException("Date format incorerect", e);
and I'm not sure how to write the test class for it.
This page should tell you everything you need to know. For the simplest case, which seems to be your case, just do this:
#Test(expected= CustomException.class)
public void myTest() {
MyObject obj = new MyObject();
obj.doSomethingThatMightThrowCustomException();
}
I hope this can help you.
public class YourTestClass
{
#Test
public void yourTestMethodName() throws CustomeException {
//your logic goes here.
if (condition) {
throw new CustomeException(<Message to display while throwing an error>);
}
}
}
Also you can try the following site http://junit.sourceforge.net/javadoc/org/junit/Test.html

Uncatchable ChuckNorrisException

Is it possible to construct a snippet of code in Java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?
Thoughts that came to mind are using for example interceptors or aspect-oriented programming.
I haven't tried this, so I don't know if the JVM would restrict something like this, but maybe you could compile code which throws ChuckNorrisException, but at runtime provide a class definition of ChuckNorrisException which does not extend Throwable.
UPDATE:
It doesn't work. It generates a verifier error:
Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow. Program will exit.
UPDATE 2:
Actually, you can get this to work if you disable the byte code verifier! (-Xverify:none)
UPDATE 3:
For those following from home, here is the full script:
Create the following classes:
public class ChuckNorrisException
extends RuntimeException // <- Comment out this line on second compilation
{
public ChuckNorrisException() { }
}
public class TestVillain {
public static void main(String[] args) {
try {
throw new ChuckNorrisException();
}
catch(Throwable t) {
System.out.println("Gotcha!");
}
finally {
System.out.println("The end.");
}
}
}
Compile classes:
javac -cp . TestVillain.java ChuckNorrisException.java
Run:
java -cp . TestVillain
Gotcha!
The end.
Comment out "extends RuntimeException" and recompile ChuckNorrisException.java only :
javac -cp . ChuckNorrisException.java
Run:
java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain. Program will exit.
Run without verification:
java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"
After having pondered this, I have successfully created an uncatchable exception. I chose to name it JulesWinnfield, however, rather than Chuck, because it is one mushroom-cloud-laying-mother-exception. Furthermore, it might not be exactly what you had in mind, but it certainly can't be caught. Observe:
public static class JulesWinnfield extends Exception
{
JulesWinnfield()
{
System.err.println("Say 'What' again! I dare you! I double dare you!");
System.exit(25-17); // And you shall know I am the LORD
}
}
public static void main(String[] args)
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
System.out.println("There's a word for that Jules - a bum");
}
}
Et voila! Uncaught exception.
Output:
run:
Say 'What' again! I dare you! I double dare you!
Java Result: 8
BUILD SUCCESSFUL (total time: 0 seconds)
When I have a little more time, I'll see if I can't come up with something else, as well.
Also, check this out:
public static class JulesWinnfield extends Exception
{
JulesWinnfield() throws JulesWinnfield, VincentVega
{
throw new VincentVega();
}
}
public static class VincentVega extends Exception
{
VincentVega() throws JulesWinnfield, VincentVega
{
throw new JulesWinnfield();
}
}
public static void main(String[] args) throws VincentVega
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
}
catch(VincentVega vv)
{
}
}
Causes a stack overflow - again, exceptions remain uncaught.
With such an exception it would obviously be mandatory to use a System.exit(Integer.MIN_VALUE); from the constructor because this is what would happen if you threw such an exception ;)
Any code can catch Throwable. So no, whatever exception you create is going to be a subclass of Throwable and will be subject to being caught.
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
System.exit(1);
}
}
(Granted, technically this exception is never actually thrown, but a proper ChuckNorrisException can't be thrown -- it throws you first.)
Any exception you throw has to extend Throwable, so it can be always caught. So answer is no.
If you want to make it difficult to handle, you can override methods getCause(), getMessage(), getStackTrace(), toString() to throw another java.lang.ChuckNorrisException.
My answer is based on #jtahlborn's idea, but it's a fully working Java program, that can be packaged into a JAR file and even deployed to your favorite application server as a part of a web application.
First of all, let's define ChuckNorrisException class so that it doesn't crash JVM from the beginning (Chuck really loves crashing JVMs BTW :)
package chuck;
import java.io.PrintStream;
import java.io.PrintWriter;
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
}
#Override
public Throwable getCause() {
return null;
}
#Override
public String getMessage() {
return toString();
}
#Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
}
#Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
}
}
Now goes Expendables class to construct it:
package chuck;
import javassist.*;
public class Expendables {
private static Class clz;
public static ChuckNorrisException getChuck() {
try {
if (clz == null) {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("chuck.ChuckNorrisException");
cc.setSuperclass(pool.get("java.lang.Object"));
clz = cc.toClass();
}
return (ChuckNorrisException)clz.newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
And finally the Main class to kick some butt:
package chuck;
public class Main {
public void roundhouseKick() throws Exception {
throw Expendables.getChuck();
}
public void foo() {
try {
roundhouseKick();
} catch (Throwable ex) {
System.out.println("Caught " + ex.toString());
}
}
public static void main(String[] args) {
try {
System.out.println("before");
new Main().foo();
System.out.println("after");
} finally {
System.out.println("finally");
}
}
}
Compile and run it with following command:
java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main
You will get following output:
before
finally
No surprise - it's a roundhouse kick after all :)
In the constructor you could start a thread which repeatedly calls originalThread.stop (ChuckNorisException.this)
The thread could catch the exception repeatedly but would keep throwing it until it dies.
No. All exceptions in Java must subclass java.lang.Throwable, and although it may not be good practice, you can catch every type of exception like so:
try {
//Stuff
} catch ( Throwable T ){
//Doesn't matter what it was, I caught it.
}
See the java.lang.Throwable documentation for more information.
If you're trying to avoid checked exceptions (ones that must be explicitly handled) then you will want to subclass Error, or RuntimeException.
Actually the accepted answer is not so nice because Java needs to be run without verification, i.e. the code would not work under normal circumstances.
AspectJ to the rescue for the real solution!
Exception class:
package de.scrum_master.app;
public class ChuckNorrisException extends RuntimeException {
public ChuckNorrisException(String message) {
super(message);
}
}
Aspect:
package de.scrum_master.aspect;
import de.scrum_master.app.ChuckNorrisException;
public aspect ChuckNorrisAspect {
before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
throw chuck;
}
}
Sample application:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
catchAllMethod();
}
private static void catchAllMethod() {
try {
exceptionThrowingMethod();
}
catch (Throwable t) {
System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
}
}
private static void exceptionThrowingMethod() {
throw new ChuckNorrisException("Catch me if you can!");
}
}
Output:
Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
at de.scrum_master.app.Application.main(Application.java:5)
A variant on the theme is the surprising fact that you can throw undeclared checked exceptions from Java code. Since it is not declared in the methods signature, the compiler won't let you catch the exception itself, though you can catch it as java.lang.Exception.
Here's a helper class that lets you throw anything, declared or not:
public class SneakyThrow {
public static RuntimeException sneak(Throwable t) {
throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
}
private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
throw (T) t;
}
}
Now throw SneakyThrow.sneak(new ChuckNorrisException()); does throw a ChuckNorrisException, but the compiler complains in
try {
throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}
about catching an exception that is not thrown if ChuckNorrisException is a checked exception.
The only ChuckNorrisExceptions in Java should be OutOfMemoryError and StackOverflowError.
You can actually "catch" them in the means that a catch(OutOfMemoryError ex) will execute in case the exception is thrown, but that block will automatically rethrow the exception to the caller.
I don't think that public class ChuckNorrisError extends Error does the trick but you could give it a try. I found no documentation about extending Error
Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?
Yes, and here's the answer: Design your java.lang.ChuckNorrisException such that it is not an instance of java.lang.Throwable. Why? An unthrowable object is uncatchable by definition because you can never catch something that can never be thrown.
You can keep ChuckNorris internal or private and encapsulate him or swollow him...
try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }
Two fundamental problems with exception handling in Java are that it uses the type of an exception to indicate whether action should be taken based upon it, and that anything which takes action based upon an exception (i.e. "catch"es it) is presumed to resolve the underlying condition. It would be useful to have a means by which an exception object could decide which handlers should execute, and whether the handlers that have executed so far have cleaned things up enough for the present method to satisfy its exit conditions. While this could be used to make "uncatchable" exceptions, two bigger uses would be to (1) make exceptions which will only be considered handled when they're caught by code that actually knows how to deal with them, and (2) allow for sensible handling of exceptions which occur in a finally block (if a FooException during a finally block during the unwinding of a BarException, both exceptions should propagate up the call stack; both should be catchable, but unwinding should continue until both have been caught). Unfortunately, I don't think there would be any way to make existing exception-handling code work that way without breaking things.
It is easily possible to simulate a uncaught exception on the current thread. This will trigger the regular behavior of an uncaught exception, and thus gets the job done semantically. It will, however, not necessarily stop the current thread's execution, as no exception is actually thrown.
Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.
This is actually useful in (very rare) situations, for example when proper Error handling is required, but the method is invoked from a framework catching (and discarding) any Throwable.
Call System.exit(1) in the finalize, and just throw a copy of the exception from all the other methods, so that the program will exit.

Categories