I have a common project with some shared code that is being used in another project. I'm trying to convert/map the exception from the common project CommonException to a new type of Exception let's call it SuperAwesomeException.
The aim is to have a generic way of handling all custom exceptions in the project.
I've attempted to do this using an UncaughtExceptionHandler. This seems to work when running the project but not from within JUnit, since that wraps each test in a try/catch block as described here.
public final class ExceptionHandler implements Thread.UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread thread, Throwable exception) {
if (exception instanceof CommonException) {
throw new SuperAwesomeException(exception.getMessage());
}
if (exception instanceof SuperAwesomeException) {
throw new CommonException(exception.getMessage());
}
else {
System.out.println("ERROR! caught some other exception I don't really care about");
System.out.println("Not doing anything");
}
}
}
Is there another way I can map from one Exception to another or can I somehow tell JUnit not to catch certain exceptions and check the Exception is mapped to the correct one?
UPDATE - How I initially tried to write the Test:
public class ClassThatThrowsException {
ClassThatThrowsException() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
}
public void doSomething() {
throw new CommonException("Something boring blew up!");
}
}
public class ClassThatThrowsExceptionTest {
#Test(expected=SuperAwesomeException.class)
public void testAwesome() {
ClassThatThrowsException c = new ClassThatThrowsException();
c.doSomething();
}
}
which throws:
java.lang.Exception: Unexpected exception, expected<SuperAwesomeException> but was<CommonException>
The problem is: when you are using JUnit, the framework will catch your exception. Therefore the uncaught exception handler isn't called in the first place!
See here for more details.
Thus, you have to do two things:
A) write tests that make sure that your exception handler implementation works as desired
#Test(expected=SuperAwesomeException.class)
public void testAwesome() {
new ExceptionHandler().uncaughtException(null, new CommonException("whatever"));
}
B) thest the plumbing - you want to make sure that this specific uncaught handler gets actually set by your code:
#Test
public void testDefaultHandlerIsSet() {
// creating a new instance should update the handler!
new ClassThatThrowsException();
Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();
assertThat(handler, not(nullValue()));
assertThat(handler, instanceOf(ExceptionHandler.class));
}
Finally - please note: you should not just do new XException(oldException.getMessage). Rather go for new XException("some message, oldException).
In other words: you got a cause here; so you better use the incoming exception as cause within the new one you intend to throw. Otherwise you loose all stack trace information.
Related
Let's suppose I have this class:
public class Obj1{
...
public void do_Something(int someParameter) throws SomeException {
if(...) throw new SomeException();
...
}
...
}
then, somewhere
public class Obj2{
...
public void do_SomeOtherThing(Obj1 obj1){
obj1.do_Something();
//apparently the only solution is try-catching it directly, even if I'm not in the main...
...
}
I've learned that exceptions should only be thrown by METHOD, and catched by MAIN, so, my question is: is try-catch the unique way to handle sub-method exceptions, or the most external method (do_SomeOtherThing) will throw it, so that I can try-catch it directly in main, deleting the try-catch in Object2 class?
Basically, can I do as follows?
public static void main(String[] args){
Object1 obj1 = new Object1();
Object2 obj2 = new Object2();
try{
obj2.do_SomeOtherThing(obj1);
}
catch(SomeException e){
...
}
}
or not?
A checked exception is part of the contract that a method has with its caller, and a thrown exception will always need to be handled one way or another.
The correct answer depends on the exact situation:
The caller can handle the exception:
String getStringFromRemoteServer() throws IOException { ... }
String getConfigString() {
try {
return getStringFromRemoteServer();
} catch (IOException e) {
LOG.warn("Failed to contact server, using local version.", e);
return getLocalString();
}
}
In this case we have an alternative source of the data we need, so if the preferred method fails we catch the exception, log it (so that we know a problem exists with our network) and call the alternative.
The exception is fatal, and we don't want any function higher in the call tree to try to handle it.
Configuration parseConfiguration(String configString) throws ParseException { ... }
void loadConfiguration() {
try {
this.globalConfig = parseConfiguration(getConfigString());
} catch (ParseException e) {
throw new RuntimeException("Corrupted config", e);
}
}
In this case an exception means that the configuration of our application is fatally broken. There is no point in trying to handle this error, and no point in any of our callers trying to handle it, so declaring throws on loadConfiguration() would just be confusing clutter. We wrap the exception in a RuntimeException and rethrow it. Note that we don't log it -- there will be some top level reporting of uncaught exceptions, so logging it here would be repetition.
It is still valuable to have parseConfiguration() throw a checked exception, because when we are calling it from the interactive configuration editor we catch the exception and display an error message to the user.
Maybe our caller can handle the exception.
int stringToInteger(String s) throws BadNumberException { ... }
String decimalStringToHexString(String s) throws BadNumberException {
return intToHex(stringToInteger(s));
}
In this case we are not changing the meaning of the exception -- decimalStringToHexString is converting a number from a string, and one possible outcome is that the string is illegal. Our caller needs to be aware of that as a possible outcome, just as callers of stringToInteger() are, so we simply declare the exception and let our caller handle it. Our caller knows the context they are using the number in, so they can decide how to handle the exception.
A couple of rules:
Never completely ignore an exception (OK, maybe InterruptedException). If you write try { ... } catch (Exception e) {} the empty catch clause will make it hard to spot why your code doesn't work.
When you wrap an exception, always include the original exception as the cause.
I want a shared library to wrap the exceptions from within and re-throw it as an application specific exception for those that can't handle them.
What I currently have is a library exception with a static method that sets the application specific exception class that I instantiate via reflection in case a exception being thrown.
My goal is to have a single app specific exception that can be handled gracefully by a common code.
Is there a better way to do this?
lib.LibExUtil.java
class LibExUtil {
static Class<? extends RuntimeException> ex = RuntimeException.class;
public static setAppEx(Class<? extends RuntimeException> ex) {
this.ex = ex;
}
static RuntimeException wrap(Throwable t) {
return (RuntimeException)ex
.getDeclaredConstructor(new Class[] {Throwable.class}).newInstance(new Object[] {t})
}
}
lib.SomeUtil.java
static void utilMethod() {
try {
// code with checked exception
} catch (Exception ex) {
throw LibExUtil.wrap(ex);
}
}
myApp.MyAppEx.java
public class MyAppEx extends RuntimeException {
MyAppEx(Throwable t) {super(t);}
}
myApp.Client.java
// initialization
LibExUtil.setAppEx(myApp.MyAppEx.class); // optional
void method() {
SomeUtil.utilMethod();
}
For maintainability you generally want to avoid app specific functionality in a shared library.
It would make more sense to throw a library specific exception and wrap it at the app level if that is your use case.
Library exception:
public class LibraryException extends Exception {
LibraryException(Throwable t) {super(t);}
}
lib.SomeUtil.java
static void utilMethod() {
try {
// code with checked exception
} catch (Exception ex) {
throw new LibraryException(ex);
}
}
myApp.Client.java
void method() {
try{
SomeUtil.utilMethod();
} catch (LibraryException e) {
throw new MyAppEx(e);
}
}
In your example your library method SomeUtil.utilMethod(); has done some work and which resulted in an exception. It would be better that util method through some library defined exception alert the user that what went wrong with it.
Another issue is in case of multi project setup like maven if one module wants to throw a different exception then other module and the developer forgets to call static method then your library method will throw some misleading exception. Avoid this pattern.
What I want is a standard JDK class that look like this:
interface ExplodingRunnable {
void run() throws Exception;
}
Callable is no good, because its call() method is required to return a value, but I need a void.
Runnable is no good, because its run() method doesn't declare throws Exception.
I sort of need a combination of the two. Any ideas?
EDIT: I should have mentioned that I tried Callable<Void> but it requires you to define a method:
public Void call() {
// run your code;
return null; // ugly!
}
I'm looking for something a bit nicer.
Why do I want this?
I'm implementing a standard why of catching "will never happen" Exceptions (they will never happen, but various APIs define their methods throwing Exceptions) and throwing any Exceptions that might occur by wrapping them in an (unchecked) RuntimeException, so the caller can simply pass a "ExplodingRunnable" in and not have to code loads of perfunctory try/catch blocks that will never be exercised.
FINAL EDIT It looks like what I was looking for doesn't exist. The accepted answer is the closest to "correct", but it looks like there is no solution to answer the question as asked.
Could you just use Callable<Void>?
An interface with only one method, which returns void and throws Exception.
Among all java and javax classes, only one fits that description:
package java.lang;
public interface AutoCloseable
{
void close() throws Exception;
}
Well... the word "close" has many meanings...
You want to surround a bunch of statements with some extra handling, there is no sin to define your own interface here. You may find that your API requires users to learn 4 new phrases
Util.muckException( new ExplodingRunnable() { public void run() throws Exception
^1 ^2 ^3 ^4
You can actually cut down two, and user code would look like this
new MuckException(){ public void run() throws Exception
{
statement_1;
...
statement_n;
}};
public abstract class MuckException
{
public abstract run() throws Exception;
public MuckException()
{
try{ run(); }
catch(Exception e){ throw new Error(e); }
}
}
Just use Callable, ignore the return value and document things as ignoring the returned value and recommend returning null. Just because you can return something does not mean you have to.
I would just use Callable<Void> and learn to love it. ;)
You can have the checked exception not declared with the following.
Runnable runs = new Runnable() {
public void run() {
try {
// do something
} catch(Exception e) {
// rethrows anything without the compiler knowing.
// the method is deprecated but can be used on the current thread.
Thread.currentThread().stop(e);
}
}
});
Future future = executorService.submit(run);
try {
future.get();
} catch (ExecutionException ee) {
Throwable e = ee.getCause(); // can be the checked exception above.
}
and not have to code loads of perfunctory try/catch blocks that will never be exercised.
I had the same issue and fixed it a little differently
// Exceptions class
public RuntimeException wrap(Exception e) {
return e instanceof RuntimeException ? ((RuntimeException)e) : new RuntimeException(e);
}
// user code
try {
foo.bar();
} catch (Exception e) {
throw Exceptions.wrap(e);
}
Ok I have a method that kicks off an object that deasl with data - a kind of factory.
The factory splits data and sends the data that is split to custom objects that further process/refine the data.
My problem is I log errors with an object that basically just appends the strings together into a log of error. Some errors are ok - meaning the flow of program can continue - however some are serious and therefore the process needs to terminate and I need to throw the error log back to the original method. And stop processing the data at that point or it could mess things up.
The original method returns a string you see. I don't have to worry about how the method returns the error just need to get it to it.
Thanks
It sounds like you should be throwing an exception when you hit a serious error and have the call to the factory within a try catch statement to handle the errors it can generate.
Have a look here http://download.oracle.com/javase/tutorial/essential/exceptions/throwing.html for more information.
The basic code would be
Exception e = new Exception();
throw e;
However you could look at creating your own exception class to contain more information about the specific error caused.
Edit: You mention having an error log to return, a custom exception could have this included within it.
Double Edit:
Somthing like
public class BadFactoryException extends Exception{
private String log;
public BadFactoryException(String log){
this.log = log
}
}
With the factory method that can throw it being something like
public returntype factory throws BadFactoryException(input){
try{
//code goes here
}catch(Exception e){
throw new BadFactoryExeption(log);
}
}
You've just described exceptions and exception handling, a feature of Java since day one.
You don't mention Exceptions in your question - do you use them already?
If not, this is exactly what they are made for.
If you do, then you need to rethink how you are catching the exceptions for your logging.
I'm not a Java person, but I think that you need to use a try {...} catch (error) {...} block. When the desired error is caught, run System.exit(). Here's an example:
try {
/* Do your stuff here */
} catch (ExceptionType name) {
/* Oh noes, a fatal error! */
print('Oh noes!');
System.exit()
}
Is this what you were looking for?
Basic tutorial on exceptions: http://download.oracle.com/javase/tutorial/essential/exceptions/
And another good article: http://www.javaworld.com/javaworld/jw-07-1998/jw-07-exceptions.html
If you want to devide critical situations of non critical just do this:
try {
// get here all your work
} catch (TerribleException e) {
// log and exit the application
}
and in your work just don't throw any exceptions. Simple log the situation and continue the work. So all you need is to define what situations should stop the execution, then throw some Exception in that place and catch it in the class which launches the work.
Ok this is what I wanted..finally figured it out.
4 classes including a custom exception.
package ExceptionTest;
public class Main {
public static void main(String[] args) {
exceptionTester();
}
private static void exceptionTester(){
try{
new FirstLevelObj().begin();
}
catch(MyException e){
System.out.println("Its worked!");
e.printStackTrace();
}
finally{
System.out.println("Oh young man..This Class doth created the other classes! \nAnd has now thrown the exception!");
}
}
}
package ExceptionTest;
public class FirstLevelObj {
private SecondLevelObj second;
public FirstLevelObj() throws MyException{
}
protected void begin()throws MyException{
try{
second = new SecondLevelObj();
second.start();
}
catch(MyException e){
throw new MyException("This Is The One!");
}
finally{
System.out.println("And finally..");
}
}
}
package ExceptionTest;
public class SecondLevelObj {
public SecondLevelObj(){
}
protected void start() throws MyException{
for(int i = 0; i<10; i ++){
if(i == 6){
System.out.println("Exception should be thrown:");
throw new MyException("An Error Hath Occurred Young Man!");
}
else{
System.out.println(i);
}
}
}
}
package ExceptionTest;
public class MyException extends Exception{
public MyException(String s){
super(s);
}
}
I am creating some multi-threaded code, and I have created a JobDispatcher class that creates threads. I want this object to handle any unhandled exceptions in the worker threads, and so I am using
Thread.setUncaughtExceptionHandler(this);
Now, I would like to test this functionality - how can I generate an unhandled exception in the run() method of my worker object?
Just throw any exception.
E.g.:
throw new RuntimeException("Testing unhandled exception processing.");
Complete:
public class RuntimeTest
{
public static void main(String[] a)
{
Thread t = new Thread()
{
public void run()
{
throw new RuntimeException("Testing unhandled exception processing.");
}
};
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
System.err.println(t + "; " + e);
}
});
t.start();
}
}
What's the problem with just throwing an exception:
throw new Exception("This should be unhandled");
Inside your run method. And of course, not catching it. It should trigger your handler.
You should throw some unchecked exception. An unchecked exception does not require your code to handle it, and is therefore a good candidate to make all the way down the call stack.
You can choose RuntimeException for example, or even something like AssertionError, if you want to minimize the chances that some part of the code catches the exception and handles it before it reaches your handler.
just add this code and you'll get unhandled exception without lint error:
int i = 1/0;