14

I don't understand when AsyncListener#onError method is called. Javadoc doesn't help:

Notifies this AsyncListener that an asynchronous operation has failed to complete.

How could it fail? How can I reproduce this error?

UPDATE:

// in HttpServlet doGet method
AsyncContext asyncContext = req.startAsync();
asyncContext.addListener(new AsyncListener() {
    // some code
    @Override
    public void onError(AsyncEvent event) {
        // when is it called?
    }
});
executeInSomeOtherThread(asyncContext);

What do I need to do in other thread to fail this async operation?

dream brother
  • 315
  • 2
  • 9

1 Answers1

6

onError will be called if there was an Exception thrown while carrying out the asynchronous operation.

They are typically Throwables that extend java.io.IOException caused by I/O failures because of an unreliable connection or protocol level exceptions due to a logical error because of a mismatch between the client and the server.

You can get the Throwable when onError is invoked by calling:

event.getThrowable();

EDIT to address mjaggard's follow-on questions

Forgetting about AsyncContext for a second, consider the following class:

public class MyRunnableClass implements Runnable {
    private Listener mListener;

    interface Listener {
        void onError(Throwable error);
    }

    public void setListener(Listener listener) {
        mListener = listener;
    }

    @Override
    public void run() {
        // Some important code to be executed goes here

        // Pretend an exception was caught in a try/catch/finally
        // block that was doing an I/O operation

        Throwable someError = new IOException();

        if (mListener != null) {
            mListener.onError(someError);
        }
    }
}

Is it more clear now how the listener's onError method will be invoked because an exception was raised when MyRunnableClass's run method was invoked?

MyRunnableClass mrc = new MyRunnableClass();
mrc.setListener(new Listener() {
    @Override
    public void onError(Throwable error) {

    }
});

Executors.newSingleThreadScheduledExecutor().schedule(mrc, 1000L, TimeUnit.MILLISECONDS);

This is no different from how an AsyncContext holds onto a listener and notifies it if it encounters an exception that it wishes to report to the listener. How the run method gets invoked is really secondary to the fact that the owner of the code being executed is also the one that holds a reference to the listener.

Michael Krause
  • 4,689
  • 1
  • 21
  • 25
  • Can you show with a code example please? As far as I understand it, your execution in the other thread is done however you want but generally with an Executor. That doesn't know about the AsyncContext so how can the exception get there? – mjaggard Jul 31 '17 at 06:50
  • As with the run() method of Thread class , we cannot allow to declare a exception in throws class or allow a uncaught exception because we are not actually calling the run method , its the java thread system who manages it. So to add what has been said above by Michael , java thread system must be catching those exception and passing it on to onError() while calling it. – rootExplorr Jul 31 '17 at 11:50
  • But the Java thread system doesn't have access to the AsyncListener or any way to link a thread to the listener. – mjaggard Aug 02 '17 at 09:51
  • Darn it, silly stackoverflow has awarded my points to what looks to me like a wrong answer :-( – mjaggard Aug 04 '17 at 17:21
  • @mjaggard Please see my edited answer that I hope addresses your questions. – Michael Krause Aug 04 '17 at 18:31