fix(browser): retain malformed redirect diagnostics

This commit is contained in:
morluto 2026-10-10 04:58:26 +08:00
parent abf5e243c4
commit 617cd84d27
3 changed files with 57 additions and 5 deletions

View File

@ -180,6 +180,15 @@ class SourceMapEncodingError extends Error {
}
}
class SourceMapRedirectLocationError extends Error {
constructor(url: string, location: string) {
super(
`Source-map redirect from ${JSON.stringify(url)} supplied an invalid Location URL: ${JSON.stringify(location)}.`,
);
this.name = "SourceMapRedirectLocationError";
}
}
const fetchOne = async (
request: WebSourceMapRequest,
input: AnalyzeWebBundleInput,
@ -250,11 +259,11 @@ const fetchOne = async (
return emptySourceMapItem(
request,
"fetch_failed",
cause instanceof SourceMapSizeLimitError
cause instanceof SourceMapRedirectLocationError ||
cause instanceof SourceMapSizeLimitError ||
cause instanceof SourceMapDeadlineError
? cause.message
: cause instanceof SourceMapDeadlineError
? cause.message
: "Source-map fetch or validation failed.",
: "Source-map fetch or validation failed.",
);
}
};
@ -296,7 +305,11 @@ const fetchFollowingApprovedRedirects = async (
const location = response.headers.get("location");
if (location === null) return { response, fetchedUrl: current };
await response.body?.cancel();
current = new URL(location, current).href;
try {
current = new URL(location, current).href;
} catch {
throw new SourceMapRedirectLocationError(current, location);
}
}
};

View File

@ -143,6 +143,7 @@ describe("CdpBrowserProvider: approved accessibility and source capture", () =>
items: [
{
status: "included",
declared_url: `${browser.allowedOrigin}/app.js.map?token=map-secret`,
original_sources: [
expect.objectContaining({
source: `${browser.allowedOrigin}/src/main.ts`,

View File

@ -85,3 +85,41 @@ it.each([
}
},
);
it("keeps the declared URL and reports malformed redirect Location evidence", async () => {
const declaredUrl = "https://app.example.test/declared.map";
const input = analyzeWebBundleInputSchema.parse({
cdp_endpoint: "http://127.0.0.1:9222",
target_id: "selected-page",
allowed_origins: ["https://app.example.test"],
fetch_source_maps: true,
});
const result = await fetchWebSourceMaps(
[
{
scriptKey: `scr_${"1".repeat(64)}`,
declaredUrl,
fetchUrl: declaredUrl,
},
],
input,
undefined,
{
fetch: () =>
Promise.resolve(
new Response(null, {
status: 302,
headers: { location: "http://[invalid" },
}),
),
},
);
expect(result.items[0]).toMatchObject({
status: "fetch_failed",
declared_url: declaredUrl,
limitation: expect.stringContaining("invalid Location URL"),
});
expect(result.items[0]?.limitation).toContain(declaredUrl);
expect(result.items[0]?.limitation).toContain("http://[invalid");
});