-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(remix-dev): update
handleError
to properly receive `ErrorRespon…
…se` instances (#7211)
- Loading branch information
1 parent
25e5d32
commit 3720c39
Showing
6 changed files
with
273 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@remix-run/server-runtime": patch | ||
--- | ||
|
||
Fix `handleError` method to correctly receive `ErrorResponse` instances on `?_data` and resource route requests. It now receives the `ErrorResponse` instance the same way a document request would. Users can leverage `isRouteErrorResponse`to detect these error instances and log accordingly. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
226 changes: 226 additions & 0 deletions
226
packages/remix-server-runtime/__tests__/handle-error-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
import { ErrorResponse } from "@remix-run/router"; | ||
|
||
import type { ServerBuild } from "../build"; | ||
import { createRequestHandler } from "../server"; | ||
import { json } from "../responses"; | ||
|
||
function getHandler(routeModule = {}, entryServerModule = {}) { | ||
let routeId = "root"; | ||
let handleErrorSpy = jest.fn(); | ||
let build = { | ||
routes: { | ||
[routeId]: { | ||
id: routeId, | ||
path: "/", | ||
module: { | ||
default() {}, | ||
...routeModule, | ||
}, | ||
}, | ||
}, | ||
entry: { | ||
module: { | ||
handleError: handleErrorSpy, | ||
default() {}, | ||
...entryServerModule, | ||
}, | ||
}, | ||
} as unknown as ServerBuild; | ||
|
||
return { | ||
handler: createRequestHandler(build), | ||
handleErrorSpy, | ||
}; | ||
} | ||
|
||
describe("handleError", () => { | ||
describe("document request", () => { | ||
it("provides user-thrown Error", async () => { | ||
let error = new Error("💥"); | ||
let { handler, handleErrorSpy } = getHandler({ | ||
loader() { | ||
throw error; | ||
}, | ||
}); | ||
let request = new Request("http://example.com/"); | ||
await handler(request); | ||
expect(handleErrorSpy).toHaveBeenCalledWith(error, { | ||
request, | ||
params: {}, | ||
context: {}, | ||
}); | ||
}); | ||
|
||
it("provides router-thrown ErrorResponse", async () => { | ||
let { handler, handleErrorSpy } = getHandler({}); | ||
let request = new Request("http://example.com/", { method: "post" }); | ||
await handler(request); | ||
expect(handleErrorSpy).toHaveBeenCalledWith( | ||
new ErrorResponse( | ||
405, | ||
"Method Not Allowed", | ||
new Error( | ||
'You made a POST request to "/" but did not provide an `action` for route "root", so there is no way to handle the request.' | ||
), | ||
true | ||
), | ||
{ | ||
request, | ||
params: {}, | ||
context: {}, | ||
} | ||
); | ||
}); | ||
|
||
it("provides render-thrown Error", async () => { | ||
let { handler, handleErrorSpy } = getHandler(undefined, { | ||
default() { | ||
throw new Error("Render error"); | ||
}, | ||
}); | ||
let request = new Request("http://example.com/"); | ||
await handler(request); | ||
expect(handleErrorSpy).toHaveBeenCalledWith(new Error("Render error"), { | ||
request, | ||
params: {}, | ||
context: {}, | ||
}); | ||
}); | ||
|
||
it("does not provide user-thrown Responses to handleError", async () => { | ||
let { handler, handleErrorSpy } = getHandler({ | ||
loader() { | ||
throw json( | ||
{ message: "not found" }, | ||
{ status: 404, statusText: "Not Found" } | ||
); | ||
}, | ||
}); | ||
let request = new Request("http://example.com/"); | ||
await handler(request); | ||
expect(handleErrorSpy).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
describe("data request", () => { | ||
it("provides user-thrown Error", async () => { | ||
let error = new Error("💥"); | ||
let { handler, handleErrorSpy } = getHandler({ | ||
loader() { | ||
throw error; | ||
}, | ||
}); | ||
let request = new Request("http://example.com/?_data=root"); | ||
await handler(request); | ||
expect(handleErrorSpy).toHaveBeenCalledWith(error, { | ||
request, | ||
params: {}, | ||
context: {}, | ||
}); | ||
}); | ||
|
||
it("provides router-thrown ErrorResponse", async () => { | ||
let { handler, handleErrorSpy } = getHandler({}); | ||
let request = new Request("http://example.com/?_data=root", { | ||
method: "post", | ||
}); | ||
await handler(request); | ||
expect(handleErrorSpy).toHaveBeenCalledWith( | ||
new ErrorResponse( | ||
405, | ||
"Method Not Allowed", | ||
new Error( | ||
'You made a POST request to "/" but did not provide an `action` for route "root", so there is no way to handle the request.' | ||
), | ||
true | ||
), | ||
{ | ||
request, | ||
params: {}, | ||
context: {}, | ||
} | ||
); | ||
}); | ||
|
||
it("does not provide user-thrown Responses to handleError", async () => { | ||
let { handler, handleErrorSpy } = getHandler({ | ||
loader() { | ||
throw json( | ||
{ message: "not found" }, | ||
{ status: 404, statusText: "Not Found" } | ||
); | ||
}, | ||
}); | ||
let request = new Request("http://example.com/?_data=root"); | ||
await handler(request); | ||
expect(handleErrorSpy).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
describe("resource request", () => { | ||
it("provides user-thrown Error", async () => { | ||
let error = new Error("💥"); | ||
let { handler, handleErrorSpy } = getHandler({ | ||
loader() { | ||
throw error; | ||
}, | ||
default: null, | ||
}); | ||
let request = new Request("http://example.com/"); | ||
await handler(request); | ||
expect(handleErrorSpy).toHaveBeenCalledWith(error, { | ||
request, | ||
params: {}, | ||
context: {}, | ||
}); | ||
}); | ||
|
||
it("provides router-thrown ErrorResponse", async () => { | ||
let { handler, handleErrorSpy } = getHandler({ default: null }); | ||
let request = new Request("http://example.com/", { | ||
method: "post", | ||
}); | ||
await handler(request); | ||
expect(handleErrorSpy).toHaveBeenCalledWith( | ||
new ErrorResponse( | ||
405, | ||
"Method Not Allowed", | ||
new Error( | ||
'You made a POST request to "/" but did not provide an `action` for route "root", so there is no way to handle the request.' | ||
), | ||
true | ||
), | ||
{ | ||
request, | ||
params: {}, | ||
context: {}, | ||
} | ||
); | ||
}); | ||
|
||
it("does not provide user-thrown Responses to handleError", async () => { | ||
let { handler, handleErrorSpy } = getHandler({ | ||
loader() { | ||
throw json( | ||
{ message: "not found" }, | ||
{ status: 404, statusText: "Not Found" } | ||
); | ||
}, | ||
default: null, | ||
}); | ||
let request = new Request("http://example.com/"); | ||
await handler(request); | ||
expect(handleErrorSpy).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); | ||
|
||
// let request = new Request( | ||
// "http://example.com/random?_data=routes/random&foo=bar", | ||
// { | ||
// method: "post", | ||
// // headers: { | ||
// // "Content-Type": "application/json", | ||
// // }, | ||
// } | ||
// ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.