8

I'm using a library that creates its own thread and it throws an exception. How can I catch that exception? The exception is thrown on the line marked below:

ResourceDescriptor rd = new ResourceDescriptor();
        rd.setWsType(ResourceDescriptor.TYPE_FOLDER);
        fullUri += "/" + token;
        System.out.println(fullUri);
        // >>> EXCEPTION THROWN ON THE FOLLOWING LINE <<<
        rd.setUriString(fullUri.replaceAll("_", ""));
        try{
            rd = server.getWSClient().get(rd, null);
        }catch(Exception e){
            if(e.getMessage().contains("resource was not found")){
                this.addFolder(fullUri, label, false);
                System.out.println("Folder does not exist, will be added now.");
            }else{
                System.out.println("Error Messages: " + e.getMessage());
            }
        }
Gray
  • 115,027
  • 24
  • 293
  • 354
yuejdesigner85
  • 115
  • 1
  • 1
  • 10
  • 1
    How do you call the method that throws an exeption? (And may be: How do know an exception is thrown?) – DerMike Apr 27 '12 at 14:19
  • I already try to catch the generic Exception class, but I still get Exception thrown. I googled it and it seems to be thrown by another thread from the library I'm using. The library interacts with a web application through web services. – yuejdesigner85 Apr 27 '12 at 15:01

2 Answers2

21

If you can not catch it maybe that helps you:

If you have the Thread object you can try to set a UncaughtExceptionHandler. Take a look at Thread.setUncaughtExceptionHandler(...).

Give us some more detail about the library you use and how you use it.

Ortwin Angermeier
  • 5,957
  • 2
  • 34
  • 34
  • 3
    +1 I did not know about this. This is better than my answer. – Gray Apr 27 '12 at 17:23
  • I do not have any control over the thread created by that library I'm using, so I can't explicitly set uncaught exception handler on their threads. What should I do? – yuejdesigner85 May 03 '12 at 14:36
  • Take a look at [here](http://stackoverflow.com/questions/1323408/get-a-list-of-all-threads-currently-running-in-java). That way you _could_ get a hold of the `Thread` object ;) It is of course not really a clean solution but worth a try. – Ortwin Angermeier May 03 '12 at 16:58
  • And what if I catch the exception? How can I access it ( maybe from an agent)? – NeverJr Feb 29 '16 at 22:51
7

If all you have is a Thread object then there is no way to catch any exceptions (which I assume are RuntimeException). The proper way to do this is by using the Future<?> class used by the ExecutorService but you don't have control over the code starting the Thread I assume.

If you are providing the Runnable or if you are injecting any of the code into the library, then you could wrap it in a class that catches and holds the Exception for you but that is only if the exception is in your code or is thrown from within code you are calling. Something like the following:

final AtomicReference<Exception> exception = new AtomicReference<Exception>();
Thread thread = library.someMethod(new Runnable() {
   public void run() {
      try {
         // call a bunch of code that might throw
      } catch (Exception e) {
         // store our exception thrown by the inner thread
         exception.set(e);
      }
   }
});
// we assume the library starts the thread
// wait for the thread to finish somehow, maybe call library.join()
thread.join();
if (exception.get() != null) {
   throw exception.get();
}

Also, if you are forking your own thread you can also set the uncaught exception handler:

thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
   public void uncaughtException(Thread t, Throwable e) {
      // log it, dump it to the console, or ...
   }
});

But if the thread code inside of the library cannot be wrapped by you then that won't work. If you edit your question and show some code and provide some more details, I can edit my question to provide better help.

Gray
  • 115,027
  • 24
  • 293
  • 354
  • If you're providing a `Thread` and not a `Runnable`, you can override the `join` methods. This would allow you to check if the thread exited with an exception and re-throw the exception in the joining-thread's context. – ccurtsinger Apr 27 '12 at 14:12
  • @artbristol You're right. That's unfortunate. – ccurtsinger Apr 27 '12 at 14:20
  • Currently I have no control over the library as it is compiled already. – yuejdesigner85 Apr 27 '12 at 15:31
  • Great explanation. Could you elaborate on how using a `Future` can help? – flow2k Aug 05 '18 at 06:54
  • `Future` allows you to use an executor service but still get the exceptions thrown by the thread in the pool @flow2k. – Gray Aug 06 '18 at 14:29