异步回调中的java捕获异常

xoshrz7s  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(1851)

我有一个回调,它可能抛出一个自定义异常。我试着抛出它,但是它没有被外部范围捕获,编译器也不让我捕获它,它说:“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 .
edit2:这是调用异常的方法:

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 . 为什么?因为我正在处理来自远程设备的消息,所以它是异步的。我使用某种超时来等待一个特定的消息,如果消息不来,我想重新启动整个程序。

lsmepo6l

lsmepo6l1#

请注意,在您的代码中,您没有调用 onComplete 方法,您正在定义它。
异常将被抛出到代码的单独部分,可能是单独的 Thread (似乎是异步的)。因此,“exception is never thrown is the corresponding try block”消息是正确的,因为在调用 this.sendChannelOpen(...) 方法。
你的 try-catch 语句需要 Package 调用 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();
    }
}

相关问题