Skip to content

Commit a447e8b

Browse files
brophdawg11joseph0926
authored andcommitted
Update logic for data->Response conversion to use Response.json (#14181)
1 parent fa82eb9 commit a447e8b

File tree

5 files changed

+27
-37
lines changed

5 files changed

+27
-37
lines changed

.changeset/many-beers-notice.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-router": patch
3+
---
4+
5+
[REMOVE] Update data -> Response conversion (update changelog with latest from `rotten-steaks-perform.md`)

.changeset/rotten-steaks-perform.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
"react-router": patch
33
---
44

5-
Properly handle data() values returned or thrown from resource routes and return corresponding responses with the data, status, and headers
5+
Properly convert returned/thrown `data()` values to `Response` instances via `Response.json()` in middleware and resource routes

integration/resource-routes-test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,15 +243,15 @@ test.describe("loader in an app", async () => {
243243
let res = await app.goto("/return-data");
244244
expect(res.status()).toBe(207);
245245
expect(res.headers()["x-foo"]).toBe("Bar");
246-
expect(await res.text()).toEqual("Partial");
246+
expect(await res.json()).toEqual("Partial");
247247
});
248248

249249
test("should handle data() thrown from resource routes", async ({ page }) => {
250250
let app = new PlaywrightFixture(appFixture, page);
251251
let res = await app.goto("/throw-data");
252252
expect(res.status()).toBe(207);
253253
expect(res.headers()["x-foo"]).toBe("Bar");
254-
expect(await res.text()).toEqual("Partial");
254+
expect(await res.json()).toEqual("Partial");
255255
});
256256

257257
test("should handle data() returned from resource routes through middleware", async ({
@@ -261,7 +261,7 @@ test.describe("loader in an app", async () => {
261261
let res = await app.goto("/return-data-through-middleware");
262262
expect(res.status()).toBe(207);
263263
expect(res.headers()["x-foo"]).toBe("Bar");
264-
expect(await res.text()).toEqual("Partial");
264+
expect(await res.json()).toEqual("Partial");
265265
});
266266

267267
test("should handle data() thrown from resource routes through middleware", async ({
@@ -271,7 +271,7 @@ test.describe("loader in an app", async () => {
271271
let res = await app.goto("/throw-data-through-middleware");
272272
expect(res.status()).toBe(207);
273273
expect(res.headers()["x-foo"]).toBe("Bar");
274-
expect(await res.text()).toEqual("Partial");
274+
expect(await res.json()).toEqual("Partial");
275275
});
276276

277277
test("should convert strings returned from resource routes to text responses", async ({

packages/react-router/__tests__/router/context-middleware-test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,7 @@ describe("context/middleware", () => {
17161716
respondWithJson(await q(request)),
17171717
})) as Response;
17181718
expect(res.status).toBe(404);
1719-
await expect(res.text()).resolves.toEqual("not found");
1719+
await expect(res.json()).resolves.toEqual("not found");
17201720
});
17211721

17221722
it("propagates a thrown data() response if next isn't called", async () => {
@@ -1800,7 +1800,7 @@ describe("context/middleware", () => {
18001800
respondWithJson(await q(request)),
18011801
})) as Response;
18021802
expect(res.status).toBe(404);
1803-
await expect(res.text()).resolves.toEqual("not found");
1803+
await expect(res.json()).resolves.toEqual("not found");
18041804
});
18051805

18061806
it("propagates a thrown data() response if next is called", async () => {
@@ -2775,7 +2775,7 @@ describe("context/middleware", () => {
27752775
unstable_generateMiddlewareResponse: (q) => q(request),
27762776
})) as Response;
27772777
expect(res.status).toBe(404);
2778-
await expect(res.text()).resolves.toEqual("not found");
2778+
await expect(res.json()).resolves.toEqual("not found");
27792779
});
27802780

27812781
it("propagates a thrown data() response if next isn't called", async () => {
@@ -2808,7 +2808,7 @@ describe("context/middleware", () => {
28082808
unstable_generateMiddlewareResponse: async (q) => q(request),
28092809
})) as Response;
28102810
expect(res.status).toBe(404);
2811-
await expect(res.text()).resolves.toEqual("not found");
2811+
await expect(res.json()).resolves.toEqual("not found");
28122812
});
28132813

28142814
it("propagates a returned data() response if next is called", async () => {
@@ -2842,7 +2842,7 @@ describe("context/middleware", () => {
28422842
unstable_generateMiddlewareResponse: (q) => q(request),
28432843
})) as Response;
28442844
expect(res.status).toBe(404);
2845-
await expect(res.text()).resolves.toEqual("not found");
2845+
await expect(res.json()).resolves.toEqual("not found");
28462846
});
28472847

28482848
it("propagates a thrown data() response if next is called", async () => {
@@ -2876,7 +2876,7 @@ describe("context/middleware", () => {
28762876
unstable_generateMiddlewareResponse: async (q) => q(request),
28772877
})) as Response;
28782878
expect(res.status).toBe(404);
2879-
await expect(res.text()).resolves.toEqual("not found");
2879+
await expect(res.json()).resolves.toEqual("not found");
28802880
});
28812881

28822882
describe("ordering", () => {

packages/react-router/lib/router/router.ts

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3651,6 +3651,11 @@ export function createStaticHandler(
36513651
return error;
36523652
}
36533653

3654+
if (isDataWithResponseInit(error)) {
3655+
// Convert thrown data() values to ErrorResponses for the UI
3656+
error = dataWithResponseInitToErrorResponse(error);
3657+
}
3658+
36543659
if (renderedStaticContext) {
36553660
// We rendered an HTML response and caught an error going back up
36563661
// the middleware chain - render again with an updated context
@@ -3850,8 +3855,9 @@ export function createStaticHandler(
38503855
return res;
38513856
},
38523857
(error) => {
3853-
if (isRouteErrorResponse(error)) {
3854-
return Promise.resolve(errorResponseToResponse(error));
3858+
if (isDataWithResponseInit(error)) {
3859+
// Convert thrown data() values to Responses for resource routes
3860+
return Promise.resolve(dataWithResponseInitToResponse(error));
38553861
}
38563862
if (isResponse(error)) {
38573863
return Promise.resolve(error);
@@ -5511,11 +5517,7 @@ async function callServerRouteMiddleware(
55115517
nextResult = result;
55125518
return nextResult;
55135519
} catch (e) {
5514-
nextResult = await errorHandler(
5515-
// Convert thrown data() values to ErrorResponses
5516-
isDataWithResponseInit(e) ? dataWithResponseInitToErrorResponse(e) : e,
5517-
routeId,
5518-
);
5520+
nextResult = await errorHandler(e, routeId);
55195521
return nextResult;
55205522
}
55215523
};
@@ -5550,11 +5552,7 @@ async function callServerRouteMiddleware(
55505552
return nextResult;
55515553
}
55525554
} catch (e) {
5553-
let response = await errorHandler(
5554-
// Convert thrown data() values to ErrorResponses
5555-
isDataWithResponseInit(e) ? dataWithResponseInitToErrorResponse(e) : e,
5556-
routeId,
5557-
);
5555+
let response = await errorHandler(e, routeId);
55585556
return response;
55595557
}
55605558
}
@@ -6585,10 +6583,7 @@ function isHashChangeOnly(a: Location, b: Location): boolean {
65856583
function dataWithResponseInitToResponse<D>(
65866584
data: DataWithResponseInit<D>,
65876585
): Response {
6588-
return new Response(
6589-
typeof data.data === "string" ? data.data : JSON.stringify(data.data),
6590-
data.init || undefined,
6591-
);
6586+
return Response.json(data.data, data.init ?? undefined);
65926587
}
65936588

65946589
function dataWithResponseInitToErrorResponse<D>(
@@ -6601,16 +6596,6 @@ function dataWithResponseInitToErrorResponse<D>(
66016596
);
66026597
}
66036598

6604-
function errorResponseToResponse(error: ErrorResponse): Response {
6605-
return new Response(
6606-
typeof error.data === "string" ? error.data : JSON.stringify(error.data),
6607-
{
6608-
status: error.status,
6609-
statusText: error.statusText,
6610-
},
6611-
);
6612-
}
6613-
66146599
function isDataStrategyResult(result: unknown): result is DataStrategyResult {
66156600
return (
66166601
result != null &&

0 commit comments

Comments
 (0)