Skip to content

Commit 15bfe0e

Browse files
committed
refactor(api): extract error response builder in streak route
1 parent 652af5c commit 15bfe0e

1 file changed

Lines changed: 48 additions & 42 deletions

File tree

app/api/streak/route.ts

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -166,52 +166,58 @@ export async function GET(request: Request) {
166166
},
167167
});
168168
} catch (error: unknown) {
169-
const message = error instanceof Error ? error.message : 'Unknown error';
170-
const isNotFound =
171-
message.toLowerCase().includes('not found') ||
172-
message.toLowerCase().includes('could not resolve');
173-
174-
const errBg = `#${(parseResult.success && parseResult.data.bg) || '0d1117'}`;
175-
const errAccent = `#${(parseResult.success && parseResult.data.accent) || '58a6ff'}`;
176-
const errText = `#${(parseResult.success && parseResult.data.text) || 'c9d1d9'}`;
177-
const errRadius = parseResult.success
178-
? (() => {
179-
const r = Number(parseResult.data.radius);
180-
return Number.isFinite(r) ? Math.min(32, Math.max(0, r)) : 8;
181-
})()
182-
: 8;
183-
const errSpeed = (parseResult.success && parseResult.data.speed) || '8s';
184-
185-
if (isNotFound) {
186-
const match = message.match(/"([^"]+)"|login of '([^']+)'/);
187-
const badUsername =
188-
match?.[1] ?? match?.[2] ?? (parseResult.success ? parseResult.data.user : 'unknown');
189-
const svg = generateNotFoundSVG(badUsername, errBg, errAccent, errText, errRadius, errSpeed);
190-
return new NextResponse(svg, {
191-
status: 404,
192-
headers: {
193-
'Content-Type': 'image/svg+xml',
194-
'Cache-Control': 'no-cache',
195-
'Content-Security-Policy': SVG_CSP_HEADER,
196-
},
197-
});
198-
}
169+
return buildErrorResponse(error, parseResult);
170+
}
171+
}
199172

200-
const errorSvg = `
201-
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="150">
202-
<rect width="100%" height="100%" fill="#2d0000" rx="8"/>
203-
<text x="50%" y="50%" text-anchor="middle" fill="#ffcccc">
204-
Error: ${escapeXML(message)}
205-
</text>
206-
</svg>
207-
`;
208-
209-
return new NextResponse(errorSvg, {
210-
status: 500,
173+
type ParseResult = ReturnType<typeof streakParamsSchema.safeParse>;
174+
175+
function buildErrorResponse(error: unknown, parseResult: ParseResult): NextResponse {
176+
const message = error instanceof Error ? error.message : 'Unknown error';
177+
const isNotFound =
178+
message.toLowerCase().includes('not found') ||
179+
message.toLowerCase().includes('could not resolve');
180+
181+
const errBg = `#${(parseResult.success && parseResult.data.bg) || '0d1117'}`;
182+
const errAccent = `#${(parseResult.success && parseResult.data.accent) || '58a6ff'}`;
183+
const errText = `#${(parseResult.success && parseResult.data.text) || 'c9d1d9'}`;
184+
const errRadius = parseResult.success
185+
? (() => {
186+
const r = Number(parseResult.data.radius);
187+
return Number.isFinite(r) ? Math.min(32, Math.max(0, r)) : 8;
188+
})()
189+
: 8;
190+
const errSpeed = (parseResult.success && parseResult.data.speed) || '8s';
191+
192+
if (isNotFound) {
193+
const match = message.match(/"([^"]+)"|login of '([^']+)'/);
194+
const badUsername =
195+
match?.[1] ?? match?.[2] ?? (parseResult.success ? parseResult.data.user : 'unknown');
196+
const svg = generateNotFoundSVG(badUsername, errBg, errAccent, errText, errRadius, errSpeed);
197+
return new NextResponse(svg, {
198+
status: 404,
211199
headers: {
212200
'Content-Type': 'image/svg+xml',
213-
'Cache-Control': 'public, s-maxage=60',
201+
'Cache-Control': 'no-cache',
202+
'Content-Security-Policy': SVG_CSP_HEADER,
214203
},
215204
});
216205
}
206+
207+
const errorSvg = `
208+
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="150">
209+
<rect width="100%" height="100%" fill="#2d0000" rx="8"/>
210+
<text x="50%" y="50%" text-anchor="middle" fill="#ffcccc">
211+
Error: ${escapeXML(message)}
212+
</text>
213+
</svg>
214+
`;
215+
216+
return new NextResponse(errorSvg, {
217+
status: 500,
218+
headers: {
219+
'Content-Type': 'image/svg+xml',
220+
'Cache-Control': 'public, s-maxage=60',
221+
},
222+
});
217223
}

0 commit comments

Comments
 (0)