-
Notifications
You must be signed in to change notification settings - Fork 438
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
Render 400-500 status response HTML #39
Conversation
src/core/drive/form_submission.ts
Outdated
@@ -99,7 +99,9 @@ export class FormSubmission { | |||
} | |||
|
|||
requestSucceededWithResponse(request: FetchRequest, response: FetchResponse) { | |||
if (this.requestMustRedirect(request) && !response.redirected) { | |||
if (response.unprocessableEntity) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the only special case status we want to support?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense to cover all 4xx
errors, not only 422
. 422 is pretty specific to rails scaffolding conventions where as 4xx
is more widely used for forms that have errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
422
is problematic also for Rails. Default HTML
response for invalid form is 200
, 422
is usually used only for JSON
responses. I know it can be changed, but support for default behaviour would be nicer :).
Example from rails scaffold generator:
# POST /rooms
# POST /rooms.json
def create
@room = Room.new(room_params)
respond_to do |format|
if @room.save
format.html { redirect_to @room, notice: 'Room was successfully created.' }
format.json { render :show, status: :created, location: @room }
else
format.html { render :new }
format.json { render json: @room.errors, status: :unprocessable_entity }
end
end
end
Note : I realised that form submits sent by turbo don't have the |
if (this.requestMustRedirect(request) && !response.redirected) { | ||
if (response.unprocessableEntity) { | ||
this.delegate.formSubmissionFailedWithResponse(this, response) | ||
} else if (this.requestMustRedirect(request) && !response.redirected) { | ||
const error = new Error("Form responses must redirect to another location") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the technical reason why we need to have this error triggered when the response is not a redirect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the technical reason why we need to have this error triggered when the response is not a redirect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work. I agree with your choice to expand this to cover all 4xx and 5xx responses.
fa1b6c2
to
e73f9e8
Compare
Related to hotwired/turbo-rails#12 Related to hotwired/turbo-rails#34 Typically, Turbo expects each FormSubmission request to result in a redirect to a new Location. When a FormSubmission request fails with an HTTP Status code between 400-499 or 500-599 (e.g. [unprocessable entity][422]), render the response HTML. This commit brings the same behavior to `<turbo-frame>` elements. [422]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
e73f9e8
to
4670f2b
Compare
const responseHTML = await fetchResponse.responseHTML | ||
|
||
if (responseHTML) { | ||
debugger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤠
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For long forms, page is not scrolled to the top after submit, do you think this should be fixed natively in turbo ? |
When responding to an HTML request that had errors on the resource, responders would not set any status, which means Rails would default to `200 OK`. This has been long working like this but also a long discussion in responders to change that behavior, to be more inline with how other types of requests (like JSON/XML) handle responses by setting the HTTP status to 422 Unprocessable Entity when responding with an error. More recently with the Turbo/Hotwire library, they've added support to render form responses as errors with 4xx statuses [1], so it makes even more sense for responders to make the move here. This change now makes it respond with 422 Unprocessable Entity in such cases when the resource has errors, and should work more out of the box with Turbo/Hotwire. Please note that this is a possible breaking change if you're relying on the previous status to trigger any behavior for errors in your app. [1] hotwired/turbo#39
When responding to a non-GET HTML request that had errors on the resource, responders would not set any status, which means Rails would default to `200 OK`. This has been long working like this but also a long discussion in responders to change that behavior, to be more inline with how other types of requests (like JSON/XML) handle responses by setting the HTTP status to 422 Unprocessable Entity when responding with an error. More recently with the Turbo/Hotwire library, they've added support to render form responses as errors with 4xx statuses [1], so it makes even more sense for responders to make the move here. This change now makes responders use the 422 Unprocessable Entity status in such cases when the resource has errors, and should work more out of the box with Turbo/Hotwire. Please note that this is a possible breaking change if you're relying on the previous status to trigger any behavior for errors in your app. [1] hotwired/turbo#39
…appropriate HTTP status code (dunglas) This PR was squashed before being merged into the 5.3-dev branch. Discussion ---------- [FrameworkBundle] Add renderForm() helper setting the appropriate HTTP status code | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | no | New feature? | yes <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | n/a | License | MIT | Doc PR | todo A 422 HTTP status code should be returned after the submission of an invalid form. Some libraries including [Turbo](hotwired/turbo#39) rely on this behavior and will not display the updated form (containing errors) unless this status code is present. Rails also [recently switched to this behavior ](rails/rails#41026) by default for the same reason. I propose to introduce a new helper method rendering the form and setting the appropriate status code. It makes the code cleaner: ```php // src/Controller/TaskController.php // ... use Symfony\Component\HttpFoundation\Request; class TaskController extends AbstractController { public function new(Request $request): Response { $task = new Task(); $form = $this->createForm(TaskType::class, $task); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $task = $form->getData(); // ... return $this->redirectToRoute('task_success'); } return $this->renderForm('task/new.html.twig', $form); } } ``` Commits ------- 4c77e50 [FrameworkBundle] Add renderForm() helper setting the appropriate HTTP status code
This is required by Turbo [1]. This will be the default in Rails 7 [2]. [1] hotwired/turbo#39 [2] rails/rails@2afc905
Related to hotwired/turbo-rails#12
Related to hotwired/turbo-rails#34
Typically, Turbo expects each FormSubmission request to result in a
redirect to a new Location.
When a FormSubmission request fails with an HTTP Status code between
400-499 or 500-599 (e.g. unprocessable entity), render the
response HTML. This commit brings the same behavior to
<turbo-frame>
elements.