Skip to content

Commit 52b9895

Browse files
committed
fix: show resource validation error as response
Sometimes users are able to save broken resource for example without header value. We need to prevent failing all requests and instead fail only broken one.
1 parent a5fc5bc commit 52b9895

File tree

2 files changed

+40
-32
lines changed

2 files changed

+40
-32
lines changed

apps/builder/app/routes/rest.resources-loader.ts

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,35 @@ export const action = async ({ request }: ActionFunctionArgs) => {
2525
};
2626

2727
const requestJson = await request.json();
28+
const requestList = z.array(z.unknown()).safeParse(requestJson);
2829

29-
const computedResourcesParsed = z
30-
.array(ResourceRequest)
31-
.safeParse(requestJson);
32-
33-
if (computedResourcesParsed.success === false) {
34-
console.error(
35-
"computedResources.parse",
36-
computedResourcesParsed.error.toString()
37-
);
30+
if (requestList.success === false) {
3831
console.error("data:", requestJson);
39-
40-
throw data(computedResourcesParsed.error, {
32+
throw data(requestList.error, {
4133
status: 400,
4234
});
4335
}
4436

45-
const computedResources = computedResourcesParsed.data;
46-
47-
const responses = await Promise.all(
48-
computedResources.map((resource) => loadResource(customFetch, resource))
37+
const output = await Promise.all(
38+
requestList.data.map(async (item) => {
39+
const resource = ResourceRequest.safeParse(item);
40+
if (resource.success === false) {
41+
return [
42+
getResourceKey(item as ResourceRequest),
43+
{
44+
ok: false,
45+
data: resource.error.format(),
46+
status: 403,
47+
statusText: "Resource validation error",
48+
},
49+
];
50+
}
51+
return [
52+
getResourceKey(resource.data),
53+
await loadResource(customFetch, resource.data),
54+
];
55+
})
4956
);
50-
const output: [string, unknown][] = [];
51-
responses.forEach((response, index) => {
52-
const request = computedResources[index];
53-
output.push([getResourceKey(request), response]);
54-
});
57+
5558
return output;
5659
};

apps/builder/app/shared/resources.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,23 @@ import { fetch } from "./fetch.client";
77

88
const MAX_PENDING_RESOURCES = 5;
99

10-
export const getResourceKey = (resource: ResourceRequest) =>
11-
hash(
12-
JSON.stringify([
13-
// explicitly list all fields to keep hash stable
14-
resource.name,
15-
resource.method,
16-
resource.url,
17-
resource.searchParams,
18-
resource.headers,
19-
resource.body,
20-
])
21-
);
10+
export const getResourceKey = (resource: ResourceRequest) => {
11+
try {
12+
return hash(
13+
JSON.stringify([
14+
// explicitly list all fields to keep hash stable
15+
resource.name,
16+
resource.method,
17+
resource.url,
18+
resource.searchParams,
19+
resource.headers,
20+
resource.body,
21+
])
22+
);
23+
} catch {
24+
// guard from invalid resources
25+
}
26+
};
2227

2328
const queue = new Map<string, ResourceRequest>();
2429
const pending = new Map<string, ResourceRequest>();

0 commit comments

Comments
 (0)