Skip to content

Commit c1d888e

Browse files
authored
fix: prevent dev server crash (#17)
1 parent f1d0745 commit c1d888e

4 files changed

Lines changed: 48 additions & 4 deletions

File tree

.changeset/wet-squids-drum.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'starlight-changelogs': patch
3+
---
4+
5+
Prevents the development server from crashing when failing to fetch remote data for a changelog.
6+
7+
Previously, if some remote changelog data could not be fetched (due to network issues for example), the development server would crash. This update ensures that such failures are handled more gracefully, allowing the server to continue running. In such cases, warning messages will be logged to inform that no changelog data is available and associated pages will not be generated. The production build process remains unaffected by this change.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { LoaderContext } from 'astro/loaders'
2+
3+
export async function fetchFromLoader(
4+
url: URL,
5+
headers: HeadersInit,
6+
logger: LoaderContext['logger'],
7+
): Promise<LoaderResult> {
8+
let response: Response | undefined
9+
10+
try {
11+
response = await fetch(url, { headers })
12+
} catch (error) {
13+
if (!import.meta.env.DEV) throw error
14+
15+
logger.error(`Failed to fetch data from ${url} with the following error:`)
16+
logger.error(error instanceof Error ? error.message : String(error))
17+
logger.error('Continuing without changelog data for now, but make sure the URL is correct and accessible.')
18+
}
19+
20+
return response ? { ok: true, response } : { ok: false }
21+
}
22+
23+
type LoaderResult = { ok: true; response: Response } | { ok: false }

packages/starlight-changelogs/providers/changeset.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { toMarkdown } from 'mdast-util-to-markdown'
1010
import { toString } from 'mdast-util-to-string'
1111
import { CONTINUE, SKIP, visit } from 'unist-util-visit'
1212

13+
import { fetchFromLoader } from '../libs/net'
1314
import { throwPluginError } from '../libs/plugin'
1415
import type { VersionDataEntry } from '../loader/schema'
1516
import { slugifyVersion } from '../loader/utils'
@@ -55,7 +56,10 @@ export async function loadChangesetData(config: ChangesetProviderConfig, context
5556
})
5657
}
5758

58-
async function getChangelogContent(pathOrUrl: string | URL, { meta }: LoaderContext): Promise<ChangelogContent> {
59+
async function getChangelogContent(
60+
pathOrUrl: string | URL,
61+
{ logger, meta }: LoaderContext,
62+
): Promise<ChangelogContent> {
5963
if (typeof pathOrUrl === 'string') {
6064
if (!existsSync(pathOrUrl)) throwPluginError(`The provided changelog file path at ${pathOrUrl} does not exist.`)
6165

@@ -66,7 +70,10 @@ async function getChangelogContent(pathOrUrl: string | URL, { meta }: LoaderCont
6670

6771
const headers = new Headers()
6872

69-
const response = await fetch(pathOrUrl, { headers: getConditionalHeaders({ init: headers, meta }) })
73+
const result = await fetchFromLoader(pathOrUrl, getConditionalHeaders({ init: headers, meta }), logger)
74+
if (!result.ok) return { modified: true, content: '' }
75+
76+
const response = result.response
7077

7178
if (response.status === 304) return { modified: false }
7279
if (!response.ok)

packages/starlight-changelogs/providers/github.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getConditionalHeaders, storeConditionalHeaders } from '@ascorbic/loader
22
import type { LoaderContext } from 'astro/loaders'
33
import { z } from 'astro/zod'
44

5+
import { fetchFromLoader } from '../libs/net'
56
import { throwPluginError } from '../libs/plugin'
67
import type { VersionDataEntry } from '../loader/schema'
78
import { slugifyVersion } from '../loader/utils'
@@ -54,7 +55,10 @@ async function syncData(
5455
}
5556
}
5657

57-
async function fetchGitHubReleases(config: GitHubProviderConfig, { meta }: LoaderContext): Promise<GitHubApiResult> {
58+
async function fetchGitHubReleases(
59+
config: GitHubProviderConfig,
60+
{ logger, meta }: LoaderContext,
61+
): Promise<GitHubApiResult> {
5862
let page: string | null = '1'
5963
const entries: VersionDataEntry[] = []
6064

@@ -68,7 +72,10 @@ async function fetchGitHubReleases(config: GitHubProviderConfig, { meta }: Loade
6872
headers.set('X-GitHub-Api-Version', '2022-11-28')
6973
if (config.token) headers.set('Authorization', `Bearer ${config.token}`)
7074

71-
const response = await fetch(url, { headers: getConditionalHeaders({ init: headers, meta }) })
75+
const result = await fetchFromLoader(url, getConditionalHeaders({ init: headers, meta }), logger)
76+
if (!result.ok) return { modified: true, entries: [] }
77+
78+
const response = result.response
7279

7380
if (response.status === 304) return { modified: false }
7481
if (!response.ok) throwPluginError(`Failed to fetch GitHub data: ${response.status} - ${response.statusText}`)

0 commit comments

Comments
 (0)