Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions app/api/streak/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
calculateStreak,
calculateMonthlyStats,
aggregateCalendars,
convertLocalToUtc,

Check warning on line 16 in app/api/streak/route.ts

View workflow job for this annotation

GitHub Actions / Format · Lint · Typecheck · Test

'convertLocalToUtc' is defined but never used
chunkDaysIntoWeeks,
normalizeCalendarToTimezone,
isLeapYear,

Check warning on line 19 in app/api/streak/route.ts

View workflow job for this annotation

GitHub Actions / Format · Lint · Typecheck · Test

'isLeapYear' is defined but never used
daysInYear,
} from '@/lib/calculate';
import {
Expand Down Expand Up @@ -55,7 +55,7 @@

import { validationCache as _vc, normalizeCacheKey, cachedValidation } from './validation-cache';
// Re-alias so existing usages in this file continue to work.
const validationCache = _vc;

Check warning on line 58 in app/api/streak/route.ts

View workflow job for this annotation

GitHub Actions / Format · Lint · Typecheck · Test

'validationCache' is assigned a value but never used

const SVG_CSP_HEADER =
"default-src 'none'; style-src 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; connect-src https://fonts.gstatic.com;";
Expand Down Expand Up @@ -513,6 +513,39 @@
}
}
}
} catch (error: unknown) {
const msg = error instanceof Error ? error.message.toLowerCase() : '';
const isRateLimit = msg.includes('rate limit');
const isTimeout = isAbortError(error);
const isValidationError = msg.includes('validation');

if (!isRateLimit && !isTimeout && !isValidationError) {
const errBg = `#${sanitizeHexColor(params.bg, '0d1117')}`;
const errAccentRaw = Array.isArray(params.accent)
? params.accent[params.accent.length - 1]
: params.accent;
const errAccent = `#${sanitizeHexColor(errAccentRaw, '58a6ff')}`;
const errText = `#${sanitizeHexColor(params.text, 'c9d1d9')}`;
const errRadius = sanitizeRadius(params.radius, 8);

const svg = generateNotFoundSVG(
'User not found or private account',
errBg,
errAccent,
errText,
errRadius,
params.speed
);
return new NextResponse(svg, {
status: 200,
headers: {
'Content-Type': 'image/svg+xml; charset=utf-8',
'Cache-Control': 'no-cache',
'Content-Security-Policy': SVG_CSP_HEADER,
},
});
}
throw error;
} finally {
clearTimeout(timeoutId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ describe('SectionCard Error Resilience', () => {
);

expect(telemetrySpy).toHaveBeenCalledTimes(1);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment

const [errorArg] = telemetrySpy.mock.calls[0];
expect(errorArg).toBeInstanceOf(Error);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access

expect((errorArg as Error).message).toBe('Standard runtime exception');

consoleErrorSpy.mockRestore();
Expand Down
Loading