add pretalx data fallback when token is unavailable#49
add pretalx data fallback when token is unavailable#49mirumodapon wants to merge 3 commits intomainfrom
Conversation
Dokploy Preview Deployment
|
There was a problem hiding this comment.
Pull request overview
This PR adds a fallback path for session data generation when pretalx credentials aren’t available, so the site can still produce session JSON by proxying COSCUP’s published endpoints.
Changes:
- Make
server/utils/pretalxreturnnullwhenTOKEN/BASE_URLare missing (instead of attempting unauthenticated pretalx calls). - Add remote fallback fetches in session JSON/API routes when pretalx data is unavailable.
- Ensure
/api/sessionis included in Nuxt prerender routes.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| server/utils/pretalx/index.ts | Return null early when pretalx runtime config is missing; otherwise fetch pretalx tables as before. |
| server/routes/json/session.json.get.ts | Fallback to https://coscup.org/2026/json/session.json when pretalx data is null. |
| server/routes/api/session/index.get.ts | Fallback to https://coscup.org/2026/api/session when pretalx data is null. |
| server/routes/api/session/[id]/index.get.ts | Reworks data source for per-session endpoint, but currently introduces a runtime/type mismatch (see PR comment). |
| app/app.vue | Adds /api/session to prerender list alongside /json/session.json. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const data = await $fetch<PretalxResult>('/2026/json/pretalx.json') | ||
|
|
||
| if (!data) { | ||
| return (await $fetch('https://coscup.org/2026/api/session')) |
There was a problem hiding this comment.
$fetch will throw on non-2xx/network failures, so the if (!data) branch won’t run in the common failure case (and data is typed as non-null). To make the fallback actually work, wrap the $fetch('/2026/json/pretalx.json') in a try/catch (or use $fetch.raw) and fall back on error.
| const data = await $fetch<PretalxResult>('/2026/json/pretalx.json') | |
| if (!data) { | |
| return (await $fetch('https://coscup.org/2026/api/session')) | |
| let data: PretalxResult | null = null | |
| try { | |
| data = await $fetch<PretalxResult>('/2026/json/pretalx.json') | |
| } | |
| catch { | |
| // Fallback to remote session API on fetch error (non-2xx or network failure) | |
| return await $fetch('https://coscup.org/2026/api/session') | |
| } | |
| if (!data) { | |
| return await $fetch('https://coscup.org/2026/api/session') |
|
|
||
| export default defineEventHandler(async () => { | ||
| const data = await pretalxData() | ||
| const data = await $fetch<PretalxResult>('/2026/json/pretalx.json') |
There was a problem hiding this comment.
This internal fetch hardcodes the /2026/ base path. That makes the route brittle if app.baseURL changes (or for future years). Prefer calling the local handler without embedding the year (e.g. /json/pretalx.json via local fetch) or derive the prefix from runtime config to avoid duplicating the base path in multiple places.
| const data = await $fetch<PretalxResult>('/2026/json/pretalx.json') | |
| const data = await $fetch<PretalxResult>('/json/pretalx.json') |
There was a problem hiding this comment.
這應該要有 /2026 (?
| const id = getRouterParam(event, 'id')! | ||
|
|
||
| const data = await pretalxData() | ||
| const data = await $fetch<PretalxResult>('/2026/json/pretalx.json') |
There was a problem hiding this comment.
This path hardcodes /2026/, which couples the server logic to the current app.baseURL. To reduce future churn and avoid mismatches, prefer fetching /json/pretalx.json via local fetch (or constructing the path from app.baseURL) rather than embedding the year here.
|
|
||
| export default defineEventHandler(async () => { | ||
| const data = await pretalxData() | ||
|
|
||
| if (!data) { | ||
| return (await $fetch('https://coscup.org/2026/json/pretalx.json')) |
There was a problem hiding this comment.
When pretalxData() returns null, this route always fetches from https://coscup.org/.... If that upstream request fails, the handler will throw and callers will get a generic 500. Consider handling $fetch errors explicitly (try/catch + createError with 502/503), and optionally caching the fallback result to avoid repeated upstream requests under load.
| export default defineEventHandler(async () => { | |
| const data = await pretalxData() | |
| if (!data) { | |
| return (await $fetch('https://coscup.org/2026/json/pretalx.json')) | |
| import { createError } from 'h3' | |
| let cachedPretalxFallback: any | null = null | |
| export default defineEventHandler(async () => { | |
| const data = await pretalxData() | |
| if (!data) { | |
| if (cachedPretalxFallback) { | |
| return cachedPretalxFallback | |
| } | |
| try { | |
| const fallback = await $fetch('https://coscup.org/2026/json/pretalx.json') | |
| cachedPretalxFallback = fallback | |
| return fallback | |
| } catch (error: any) { | |
| throw createError({ | |
| statusCode: 502, | |
| statusMessage: 'Bad Gateway', | |
| message: 'Failed to fetch pretalx fallback data from coscup.org', | |
| cause: error, | |
| }) | |
| } |
| const data = await pretalxData() | ||
| const opass = pretalxToOpass(data) | ||
|
|
||
| return opass | ||
| if (!data) { | ||
| return (await $fetch('https://coscup.org/2026/json/session.json')) | ||
| } |
There was a problem hiding this comment.
The fallback uses an external $fetch('https://coscup.org/2026/json/session.json') but doesn’t handle upstream failures; $fetch will throw and the endpoint becomes a 500. Consider try/catch with a 502/503 (and optionally caching the fallback response) so behavior is predictable when the upstream is down.
This PR introduces a fallback mechanism for pretalx data, allowing the application to function even when a token is not provided.