java 在异步回调中捕获异常

java Catch exception inside a async callback

我有一个可能会抛出自定义异常的回调。 我试图抛出它,但它没有被外部作用域捕获,编译器也没有让我捕获它,它说:“Exception is never thrown is the corresponding try block”,即使它是。

这是我的代码:

public void openAsync(MessageAsyncCallback callback) {
        try {
            this.sendChannelOpen(this.getChannel(), getChannelOpenData().getFlags(), new MessageAsyncCallback() {
                @Override
                public void onComplete() throws NanoException {
//                INanoPacket message = transport.getMessageByClassName(AudioServerHandshake.class.getName());
                    INanoPacket message = transport.getMessageByClassName(AudioClientHandshake.class.getName());
                    Log.info("Got audio server handshake, trying to client-handshake it");
                    sendClientHandshakeAsync((AudioServerHandshake) message, callback);
                }
            });
        } catch (NanoException e) {
            System.exit(-2);
        }
    }

它不让我抓到 NanoException

编辑:transport.getMessageByClassName 里面我扔了一个 NanoException.

编辑2: 这是调用异常的方法:

public INanoPacket getMessageByClassName(String destClassName) throws NanoException {//} throws NanoException {
        long startTime = System.currentTimeMillis(); // fetch starting time
        INanoPacket message = this.getMessageFromTCPQueue();

        while (!(message.getClass().getName().equals(destClassName)) && isRuntimeValid(startTime)) {
            this.insertToTCPQueue(message); // put message back in queue
            message = this.getMessageFromTCPQueue();
        }

        if (!(message.getClass().getName().equals(destClassName))) {
            // timeout...
            throw new NanoException("Couldn't find destination message: " + destClassName);
        }

        return message;
    }

我什至不想在 openAsync 中处理异常,而是在调用 openAsync 的方法中处理异常。 为什么? 因为我正在处理来自远程设备的消息,所以它是异步的。我正在使用某种超时来等待特定消息,如果消息没有出现,我想重新启动整个程序。

请注意,在您的代码中您没有调用 onComplete 方法,而是定义了它。

异常将在代码的单独部分中抛出,可能是单独的 Thread(因为它似乎是异步的)。因此,“永远不会抛出异常是相应的 try 块”消息是正确的,因为调用 this.sendChannelOpen(...) 方法时永远不会抛出异常。

您的 try-catch 语句需要包装您调用 onComplete 方法的地方。因为只有调用 onComplete 方法,你才能期望 NanoException.

根据评论进行编辑: 如果你需要处理 getMessageByClassName 中抛出的异常,你可以在 onComplete 方法中处理,而不是重新抛出它。如果您想在其他地方处理它,您需要向我们提供 sendChannelOpen 方法的代码或调用回调的地方。

EDIT2(基于问题编辑): 请参阅下面的代码,作为如何在线程之间进行通信的示例。我用过 Latch,但 java.util.concurrent 中还有其他 类 可能对您有用。 顺便说一句,我不会讨论为什么要在 NanoException 上重新启动整个应用程序,尽管可能还有其他值得考虑的选项来从该异常中恢复。

import java.util.concurrent.CountDownLatch;

class NanoException extends Exception {}

interface MessageAsyncCallback {
    void onComplete() throws NanoException;
}

public class AsyncApp {
    private static final CountDownLatch errorLatch = new CountDownLatch(1);
    public static void main(String[] args) {
        new AsyncApp().run();
    }

    void run() {
        sendChannelOpen("something", new MessageAsyncCallback() {
            @Override
            public void onComplete() throws NanoException {
                // the whole try-catch-sleep is not really needed, just to wait a bit before exception is thrown
                try {
                    // not needed, just to wait a bit before exception is thrown
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new NanoException();
                }
                throw new NanoException();
            }
        });

        try {
            System.out.println("This is a main thread and we wait here, while the other thread executes...");
            errorLatch.await();
            System.out.println("Latch has reached 0, will now exit.");
            System.exit(-2);
        } catch (InterruptedException e) {
            System.out.println("Error in main thread.");
            System.exit(-1);
        }
    }

    void sendChannelOpen(String notImportant, MessageAsyncCallback troublesomeCallback) {
        runSomethingInSeparateThread(troublesomeCallback);
    }

    void runSomethingInSeparateThread(MessageAsyncCallback troublesomeCallback) {
        new Thread(() -> {
            try {
                troublesomeCallback.onComplete();
            } catch (NanoException e) {
                System.out.println("You can catch it here, and do system exit here or synchronize with main Thread as below");
                errorLatch.countDown();
            }
        }).start();
    }
}