@@ -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 ( / " ( [ ^ " ] + ) " | l o g i n o f ' ( [ ^ ' ] + ) ' / ) ;
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 ( / " ( [ ^ " ] + ) " | l o g i n o f ' ( [ ^ ' ] + ) ' / ) ;
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