-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom ErrorHandler implementation's UI changes are ignored #17352
Comments
It seems similar to #14091 |
I could debug the ErrorHandler being executed. But anything that it would change in the browser is ignored, so server side action, like logging or writing into db would work. In the handleExceptionDuringRequest code, first it runs the ErrorHandler, then if this is a UIDL request, goes to a branch that responds only with the Internal error system message. I would also mention, that we don't want to see the internal error message, after we have already customized the error behaviour. For this particular case, even a workaround would be a solution. |
All of the following examples reproduce the problem. The error handler is called, but no UI changes in the grid.addColumn(person -> {
throw new AnonException();
})
.setHeader("Name");
grid.addComponentColumn(person -> {
throw new AnonException();
})
.setHeader("Name");
grid.addColumn(LitRenderer
.<Person>of("<b>${item.name}</b>")
.withProperty("name", person -> {
throw new AnonException();
}))
.setHeader("Name"); I imagine there are other cases where an exception would trigger the problem. |
Let's take a look at
Say we have a custom error handler that modifies the UI. For example, However, no normal UIDL message is sent, as if we continue reading the method, we see that a "critical notification" message is sent. See below the following code snippet (original method) for a revised method: private void handleExceptionDuringRequest(VaadinRequest request,
VaadinResponse response, VaadinSession vaadinSession, Exception t)
throws ServiceException {
if (vaadinSession != null) {
vaadinSession.lock();
}
try {
if (vaadinSession != null) {
vaadinSession.getErrorHandler().error(new ErrorEvent(t));
}
// if this was an UIDL request, send UIDL back to the client
if (HandlerHelper.isRequestType(request, RequestType.UIDL)) {
SystemMessages ci = getSystemMessages(
HandlerHelper.findLocale(vaadinSession, request),
request);
try {
writeUncachedStringResponse(response,
JsonConstants.JSON_CONTENT_TYPE,
createCriticalNotificationJSON(
ci.getInternalErrorCaption(),
ci.getInternalErrorMessage(), null,
ci.getInternalErrorURL()));
} catch (IOException e) {
// An exception occurred while writing the response. Log
// it and continue handling only the original error.
getLogger().warn(
"Failed to write critical notification response to the client",
e);
}
} else {
// Re-throw other exceptions
throw new ServiceException(t);
}
} finally {
if (vaadinSession != null) {
vaadinSession.unlock();
}
}
} We could instead write a UIDL. This is definitely not a fix, just a workaround. private void handleExceptionDuringRequest(VaadinRequest request,
VaadinResponse response, VaadinSession vaadinSession, Exception t)
throws ServiceException {
if(vaadinSession != null) {
vaadinSession.lock();
}
try {
if(vaadinSession != null) {
vaadinSession.getErrorHandler().error(new ErrorEvent(t));
}
// if this was an UIDL request, send UIDL back to the client
if(HandlerHelper.isRequestType(request, RequestType.UIDL)) {
getRequestHandlers().forEach(requestHandler -> {
if(requestHandler instanceof UidlRequestHandler) {
try {
requestHandler.handleRequest(vaadinSession, request, response);
} catch(final IOException e) {
getLogger().warn("Failed to pass UI to client.", e);
}
}
});
} else {
// Re-throw other exceptions
throw new ServiceException(t);
}
} finally {
if(vaadinSession != null) {
vaadinSession.unlock();
}
}
} |
The issue was triaged and currently added to the backlog priority queue for further investigation |
It has been long since I have investigated this kind of cases before, but I have some example codes from the past. One approach I found working well is to set the error handler in UI init listener. Then I have proper UI reference to the latest created UI and can use ui.access(..). This was related to another ticket #10533, which includes the same code #10533 (comment) |
@TatuLund Adding the error handler in the UI init listener does not fix this problem. |
The bug is real, |
Initial issue that I have now found is that the errorHandler should work as noted, but not in the case that the error happens in an BeforeClientResponse which happens after the RPCHandler. So this is basically an exception that breaks the writing of the UIDL response and thus returns only the internal error data. So as an example if I update the button test for custom ErrorHandler from
which adds a div to
The div doesn't get added anymore and there is a internal error notification. |
Enable update of UI for beforeClientResponse execution when a custom ErrorHandler is set. Fixes #17352
Enable update of UI for beforeClientResponse execution when a custom ErrorHandler is set. Fixes #17352 Co-authored-by: Peter Czuczor <61667986+czp13@users.noreply.github.com>
Enable update of UI for beforeClientResponse execution when a custom ErrorHandler is set. Fixes #17352 Co-authored-by: Peter Czuczor <61667986+czp13@users.noreply.github.com>
Enable update of UI for beforeClientResponse execution when a custom ErrorHandler is set. Fixes #17352 Co-authored-by: Peter Czuczor <61667986+czp13@users.noreply.github.com>
Enable update of UI for beforeClientResponse execution when a custom ErrorHandler is set. Fixes #17352 Co-authored-by: Peter Czuczor <61667986+czp13@users.noreply.github.com>
For errors in beforeClientResponse handle cases where any part to the errorHandler is null Fixes #17352
For errors in beforeClientResponse handle cases where any part to the errorHandler is null Fixes #17352
For errors in beforeClientResponse handle cases where any part to the errorHandler is null Fixes #17352
For errors in beforeClientResponse handle cases where any part to the errorHandler is null Fixes #17352
For errors in beforeClientResponse handle cases where any part to the errorHandler is null Fixes #17352
This ticket/PR has been released with Vaadin 24.2.0.alpha10 and is also targeting the upcoming stable 24.2.0 version. |
This ticket/PR has been released with Vaadin 24.1.8. |
This ticket/PR has been released with Vaadin 24.0.14. |
Description of the bug
We have created a customer error handler by extending the DefaultErrorHandler class.
This is added to the session, and it would create a Dialog (or later a Notification for testing).
The feature works when the exception occurs during component constructor, in general when it is a navigation to a given target.
The feature doesn't work, when the exception occurs in the lambda passed to a grid.addComponent method.
I debugged what happens, in the non-working case the exception is caught at VaadinService.handleExceptionDuringRequest
here the set errorHandler is called on line 1586
During the execution everything looks ok, there is a UI instance, the ui component is created, and even attached to the ui. Nothing is visible in the browser.
on line 1594 writeUncachedStringResponse is called with the system internal error message, and it is set as the response.
Checking it in the browser, the response looks like:
I think the reason is, that in the above message the Vaadin server does not send the ui changes requested in the errorHandler, not even if it is wrapped in a UI.access call. These tests were running with a single browser tab open for the server, so it cannot swap the ui instance to another one.
The online documentatation does state, that the errorHandler can add a notification, or other ui changes.
https://vaadin.com/docs/latest/advanced/custom-error-handler
Expected behavior
The requested ui changes should appear in the browser, for example Dialog open.
Minimal reproducible example
Versions
The text was updated successfully, but these errors were encountered: