Closed bastien70 closed 4 months ago
Hi!
I'm open to exploring this :)
Another example. Imagine, a user is on a page that contains a dynamic form, with lots of Ajax requests. If the user leaves the tab aside and comes back to it 30 minutes later to continue typing in the form, inevitably, at the 1st Ajax request, we will have an error which will be
Why would this cause this UnprocessableEntityHttpException
error?
In general, the thinking is that, except for extraordinary situations, you should never get the error modal on production - just like how the user should never see your 500 page. And so, in the very rare circumstances when this does happen, we're not overly concerned about the UX.
In this specific case, it would be interesting to send a flash message (or other) with the appropriate message (which will therefore be taken from the translation files) telling the user that he must refresh the page and start typing again.
Showing a SweetAlert or flash message of some sort is probably not feasible since they probably won't have SweetAlert and a flash message requires a refresh to see it. The modal works because we hardcode that right into LiveComponents itself.
However, customizing the message that the user sees is feasible. A super simple solution could be to, in the prod
environment, instead of showing the 500/whatever page that's returned from the server, we show a generic. styled message - something similar to what you suggested - "telling the user that he must refresh the page and start typing again". We could even make this customizable - e.g. you are able to customize your "500 error for live components" template in the same way that you can customize your global "500 error" template. That would be accomplished by adding an event listener to the KernelException
event and, if we're currently rendering a live component & we are about to return an error page, replace the error HTML with the rendering of some other template.
If someone wants this, you can definitely send a PR for it :)
Hello!
Why would this cause this
UnprocessableEntityHttpException
error?
It's a good question, I admit I don't understand why I have this error from time to time after a long period of not having filled in the form. I will monitor this and do some tests.
However, customizing the message that the user sees is feasible. A super simple solution could be to, in the
prod
environment, instead of showing the 500/whatever page that's returned from the server, we show a generic. styled message - something similar to what you suggested - "telling the user that he must refresh the page and start typing again". We could even make this customizable - e.g. you are able to customize your "500 error for live components" template in the same way that you can customize your global "500 error" template. That would be accomplished by adding an event listener to theKernelException
event and, if we're currently rendering a live component & we are about to return an error page, replace the error HTML with the rendering of some other template.
It's a very good idea!
Okay I said nothing for the UnprocessableEntityHttpException error, it's caused by entity validation, my bad.
So no error at this level.
Otherwise the idea to have a personalized message in the modal in preprod remains present :)
We experience the same problem/situation as @bastien70 described in the ticket. We are now handling this ourselves for each live form component by doing something like below.
Component class:
#[LiveProp]
public ?string $errorMessage = null;
#[LiveAction]
public function submitAction(): RedirectResponse
{
try {
$this->errorMessage = null;
$this->submitForm();
// ... doing something with the data
return $this->redirectToRoute('...');
} catch (UnprocessableEntityHttpException $e) {
throw $e;
} catch (\Throwable $e) {
$this->errorMessage = '...';
$this->logger->critical('...');
throw $e;
}
throw new UnprocessableEntityHttpException();
}
Twig file:
{{ form(form) }}
{% if errorMessage %}
{{ errorMessage|trans }}
{% endif %}
As you can see in our case, we show the message below the form. Actually, we are also looking for a way to showing this errors as a toast/flash message, in a general way. We already found in the documentation that it's possible to register a response:error
js hook for components individually. But we are looking for a general approach were we can globally register a js hook/plugin for all this situations.
Is this something we can do already? Or maybe you guys can point us in the right direction or share your ideas.
Hey @stefliekens!
Actually, we are also looking for a way to showing this errors as a toast/flash message, in a general way. We already found in the documentation that it's possible to register a response:error js hook for components individually
Yup, I think I understand: you need some central code that is aware of / notified when ANY live component has an error. To do this, you could register an event listener on body
(e.g. have a Stimulus controller attached to body
) that listens to the live:connect
event. It looks like this got "kicked out" of the documentation when the hook system was still added, but I guess it still has its use-cases.
Anyway, this listener would be called each time a live component is added to the page and the component should be available via event.detail.component
, which you can then use to register the response:error
hook.
Let me know if that works - having this use-case in the docs would be fantastic. Or, we can make it even easier, let's do that. The use-case makes sense 👍
hi @weaverryan, thanks for your response and suggestion ! I quickly tried it and this works perfect. With this approach we can set up something generic in our application.
Below the POC code I've used:
import { Controller } from "@hotwired/stimulus"
import {toast} from "../utilities/toastr/toastr";
export default class extends Controller {
connect() {
this.element.addEventListener('live:connect', (event: Event) => this.registerErrorHandler(event.detail.component));
}
registerErrorHandler(component: Component) {
component.on('response:error', (backendResponse: BackendResponse, controls: { displayError: boolean}) => {
toast('danger', '<p>Something went wrong, try again later or please contact us.</p>');
controls.displayError = false;
});
}
}
Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?
Hello? This issue is about to be closed if nobody replies.
Hi @carsonbot, we have implemented a custom listener based on the suggestions we received in the comment. You can close the issue.
Hey, I notified two problems I have :
In dev, when we have an Ajax request which causes an error, we have a modal which is displayed on the screen with inside, Symfony which informs us about the error, as we would have with a request which is not with Ajax.
The problem is that in production environment, well it's the same, except that necessarily, instead of having Symfony informing us about the error (since we are in production), we have in the modal the 404/500/... error page
Maybe it would be a good idea (and I don't know if it's easily doable) to check the environment, and if we're in production, then don't show a modal with the 404/ 500/... but rather a bootstrap modal / sweetAlert or whatever, or a flash message, stating that an error has occurred, without displaying the 404/500/... error page?
Another example. Imagine, a user is on a page that contains a dynamic form, with lots of Ajax requests. If the user leaves the tab aside and comes back to it 30 minutes later to continue typing in the form, inevitably, at the 1st Ajax request, we will have an error which will be
In this specific case, it would be interesting to send a flash message (or other) with the appropriate message (which will therefore be taken from the translation files) telling the user that he must refresh the page and start typing again.
What do you think ?