我有一个实现 StreamResourceWriter 接口的 FileCreator 类和一个实现 ErrorHandler 的 MainErrorHandler 类。我MainErrorHandler
在我的项目中使用该类作为集中的异常处理程序,它主要记录异常并向用户显示通知。问题是 StreamResourceWriter.accept() 方法在非 UI 线程中运行,当抛出异常时,它被定向到 ErrorHandler,然后由于“ IllegalStateException:UI 实例不可用”而无法显示通知。当 FileCreator 在方法中抛出错误时,有没有办法从 MainErrorHandler 向用户显示通知窗口accept()
?
在 FileCreator 片段下方。
public class FileCreator implements StreamResourceWriter {
@Override
public void accept(OutputStream stream, VaadinSession session) throws IOException {
// Run in a non ui thread.
// Writes to OutputStream but an Exception might be thrown during this process
}
}
在 MainErrorHandler 代码段下方。
/**
* Centralized error handler
*/
public class MainErrorHandler implements ErrorHandler {
private static final Logger log = LoggerFactory.getLogger(MainErrorHandler.class);
@Override
public void error(ErrorEvent event) {
log.error("Error occurred", event.getThrowable());
//Cannot show a notification if ErrorEvent came from FileCreator.
//Will get an IllegalStateException: UI instance is not available.
Notification.show("Error occurred");
//Tried UI.getCurrent but it returns null if ErrorEvent came from FileCreator.
UI.getCurrent();
}
}
使用 Vaadin 13.0.1。
编辑
解决此问题的一种方法是将 UI 引用直接传递给 FileCreator。下面举个例子。
public class FileCreator implements StreamResourceWriter {
private UI ui;
//Pass UI reference directly
public FileCreator(UI ui){
this.ui = ui;
}
@Override
public void accept(OutputStream stream, VaadinSession session) throws IOException {
try{
// Run in a non ui thread.
// Writes to OutputStream but an Exception might be thrown during this process
}catch(Exception e){
//I don't like this since have to catch all exceptions and have to call ErrorHandeler directly with a UI reference. Also what if somewhere in code ErrorHandler is changed and is not of type MainErrorHandler.
((MainErrorHandler)VaadinSession.getCurrent().getErrorHandler()).error(e, ui);
}
}
}
正如我在评论中所说,我真的不喜欢这种方法,因为我被迫捕获所有异常,必须将 ErrorHandler 转换为 MainErrorHandler 并直接调用它。