diff --git a/src/core/drive/form_submission.ts b/src/core/drive/form_submission.ts index 9e4087dc9..48ac60130 100644 --- a/src/core/drive/form_submission.ts +++ b/src/core/drive/form_submission.ts @@ -99,7 +99,9 @@ export class FormSubmission { } requestSucceededWithResponse(request: FetchRequest, response: FetchResponse) { - if (this.requestMustRedirect(request) && !response.redirected) { + if (response.clientError || response.serverError) { + this.delegate.formSubmissionFailedWithResponse(this, response) + } else if (this.requestMustRedirect(request) && !response.redirected) { const error = new Error("Form responses must redirect to another location") this.delegate.formSubmissionErrored(this, error) } else { diff --git a/src/core/drive/navigator.ts b/src/core/drive/navigator.ts index 12cb21cd6..2fc53c12c 100644 --- a/src/core/drive/navigator.ts +++ b/src/core/drive/navigator.ts @@ -3,6 +3,7 @@ import { FetchResponse } from "../../http/fetch_response" import { FormSubmission } from "./form_submission" import { Locatable, Location } from "../location" import { Visit, VisitDelegate, VisitOptions } from "./visit" +import { Snapshot } from "./snapshot" export type NavigatorDelegate = VisitDelegate & { allowsVisitingLocation(location: Location): boolean @@ -87,8 +88,15 @@ export class Navigator { } } - formSubmissionFailedWithResponse(formSubmission: FormSubmission, fetchResponse: FetchResponse) { - console.error("Form submission failed", formSubmission, fetchResponse) + async formSubmissionFailedWithResponse(formSubmission: FormSubmission, fetchResponse: FetchResponse) { + const responseHTML = await fetchResponse.responseHTML + + if (responseHTML) { + debugger + const snapshot = Snapshot.fromHTMLString(responseHTML) + this.view.render({ snapshot }, () => {}) + this.view.clearSnapshotCache() + } } formSubmissionErrored(formSubmission: FormSubmission, error: Error) { diff --git a/src/core/frames/frame_controller.ts b/src/core/frames/frame_controller.ts index f0ca60cb0..5573b9b61 100644 --- a/src/core/frames/frame_controller.ts +++ b/src/core/frames/frame_controller.ts @@ -109,7 +109,7 @@ export class FrameController implements FetchRequestDelegate, FormInterceptorDel } formSubmissionFailedWithResponse(formSubmission: FormSubmission, fetchResponse: FetchResponse) { - + this.element.controller.loadResponse(fetchResponse) } formSubmissionErrored(formSubmission: FormSubmission, error: Error) { diff --git a/src/http/fetch_response.ts b/src/http/fetch_response.ts index 333465cd4..2d88a75e2 100644 --- a/src/http/fetch_response.ts +++ b/src/http/fetch_response.ts @@ -15,6 +15,14 @@ export class FetchResponse { return !this.succeeded } + get clientError() { + return this.statusCode >= 400 && this.statusCode <= 499 + } + + get serverError() { + return this.statusCode >= 500 && this.statusCode <= 599 + } + get redirected() { return this.response.redirected } diff --git a/src/tests/fixtures/422.html b/src/tests/fixtures/422.html new file mode 100644 index 000000000..f090036ed --- /dev/null +++ b/src/tests/fixtures/422.html @@ -0,0 +1,13 @@ + + + Unprocessable Entity + + + +

Unprocessable Entity

+ + +

Frame: Unprocessable Entity

+
+ + diff --git a/src/tests/fixtures/500.html b/src/tests/fixtures/500.html new file mode 100644 index 000000000..62f8bfa12 --- /dev/null +++ b/src/tests/fixtures/500.html @@ -0,0 +1,13 @@ + + + Internal Server Error + + + +

Internal Server Error

+ + +

Frame: Internal Server Error

+
+ + diff --git a/src/tests/fixtures/form.html b/src/tests/fixtures/form.html index d32f97499..0dd0cc9ab 100644 --- a/src/tests/fixtures/form.html +++ b/src/tests/fixtures/form.html @@ -12,6 +12,16 @@ +
+
+ + +
+
+ + +
+