Skip to content

Commit b176301

Browse files
committed
fix(docs): keep notFound inside route boundaries
1 parent 43c791f commit b176301

7 files changed

Lines changed: 71 additions & 28 deletions

src/routes/$libraryId/$version.docs.$.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { seo } from '~/utils/seo'
22
import { Doc } from '~/components/Doc'
3+
import { isDocsNotFoundError } from '~/utils/docs-errors'
34
import { loadDocsPage, resolveDocsRedirect } from '~/utils/docs'
45
import { findLibrary, getBranch, getLibrary } from '~/libraries'
56
import { DocContainer } from '~/components/DocContainer'
@@ -36,6 +37,7 @@ export const Route = createFileRoute('/$libraryId/$version/docs/$')({
3637
})
3738
} catch (error) {
3839
const isNotFoundError =
40+
isDocsNotFoundError(error) ||
3941
isNotFound(error) ||
4042
(error && typeof error === 'object' && 'isNotFound' in error)
4143

src/routes/$libraryId/$version.docs.framework.$framework.$.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from '@tanstack/react-router'
88
import { seo } from '~/utils/seo'
99
import { Doc } from '~/components/Doc'
10+
import { isDocsNotFoundError } from '~/utils/docs-errors'
1011
import { loadDocsPage, resolveDocsRedirect } from '~/utils/docs'
1112
import { getBranch, getLibrary } from '~/libraries'
1213
import { capitalize } from '~/utils/utils'
@@ -36,6 +37,7 @@ export const Route = createFileRoute(
3637
// This handles cases like switching frameworks where the same doc path doesn't exist
3738
// Check both isNotFound() and the serialized form from server functions
3839
const isNotFoundError =
40+
isDocsNotFoundError(error) ||
3941
isNotFound(error) ||
4042
(error && typeof error === 'object' && 'isNotFound' in error)
4143

src/routes/$libraryId/$version.docs.framework.$framework.{$}[.]md.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { findLibrary, getBranch } from '~/libraries'
2+
import { isDocsNotFoundError } from '~/utils/docs-errors'
23
import { loadDocs } from '~/utils/docs'
34
import { notFound, createFileRoute } from '@tanstack/react-router'
45
import { filterFrameworkContent } from '~/utils/markdown/filterFrameworkContent'
@@ -34,12 +35,22 @@ export const Route = createFileRoute(
3435

3536
const root = library.docsRoot || 'docs'
3637

37-
const doc = await loadDocs({
38-
repo: library.repo,
39-
branch: getBranch(library, version),
40-
docsRoot: root,
41-
docsPath: `framework/${framework}/${docsPath}`,
42-
})
38+
let doc
39+
40+
try {
41+
doc = await loadDocs({
42+
repo: library.repo,
43+
branch: getBranch(library, version),
44+
docsRoot: root,
45+
docsPath: `framework/${framework}/${docsPath}`,
46+
})
47+
} catch (error) {
48+
if (isDocsNotFoundError(error)) {
49+
throw notFound()
50+
}
51+
52+
throw error
53+
}
4354

4455
// Filter framework-specific content using framework from URL path
4556
const filteredContent = filterFrameworkContent(doc.content, {

src/routes/$libraryId/$version.docs.{$}[.]md.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { createFileRoute } from '@tanstack/react-router'
1+
import { createFileRoute, notFound } from '@tanstack/react-router'
22
import { getBranch, getLibrary, type LibraryId } from '~/libraries'
3+
import { isDocsNotFoundError } from '~/utils/docs-errors'
34
import { loadDocs } from '~/utils/docs'
45
import { filterFrameworkContent } from '~/utils/markdown/filterFrameworkContent'
56
import { getPackageManager } from '~/utils/markdown/installCommand'
@@ -23,12 +24,22 @@ export const Route = createFileRoute('/$libraryId/$version/docs/{$}.md')({
2324
const library = getLibrary(libraryId as LibraryId)
2425
const root = library.docsRoot || 'docs'
2526

26-
const doc = await loadDocs({
27-
repo: library.repo,
28-
branch: getBranch(library, version),
29-
docsRoot: root,
30-
docsPath,
31-
})
27+
let doc
28+
29+
try {
30+
doc = await loadDocs({
31+
repo: library.repo,
32+
branch: getBranch(library, version),
33+
docsRoot: root,
34+
docsPath,
35+
})
36+
} catch (error) {
37+
if (isDocsNotFoundError(error)) {
38+
throw notFound()
39+
}
40+
41+
throw error
42+
}
3243

3344
// Filter framework-specific content only if framework is explicitly specified
3445
const filteredContent = framework

src/utils/docs-errors.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
type DocsNotFoundError = Error & {
2+
data: { message: string }
3+
isDocsNotFound: true
4+
}
5+
6+
export function createDocsNotFoundError(message = 'No doc was found here!') {
7+
const error = new Error(message) as DocsNotFoundError
8+
9+
error.name = 'DocsNotFoundError'
10+
error.data = { message }
11+
error.isDocsNotFound = true
12+
13+
return error
14+
}
15+
16+
export function isDocsNotFoundError(
17+
error: unknown,
18+
): error is DocsNotFoundError {
19+
return (
20+
typeof error === 'object' &&
21+
error !== null &&
22+
'isDocsNotFound' in error &&
23+
error.isDocsNotFound === true
24+
)
25+
}

src/utils/docs.functions.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { notFound } from '@tanstack/react-router'
21
import { createServerFn } from '@tanstack/react-start'
32
import { setResponseHeader } from '@tanstack/react-start/server'
43
import removeMarkdown from 'remove-markdown'
@@ -9,6 +8,7 @@ import {
98
fetchRepoFile,
109
isRecoverableGitHubContentError,
1110
} from '~/utils/documents.server'
11+
import { createDocsNotFoundError } from './docs-errors'
1212
import { renderMarkdownToRsc } from './markdown'
1313
import { getCachedDocsArtifact } from './github-content-cache.server'
1414
import { buildRedirectManifest, type RedirectManifestEntry } from './redirects'
@@ -223,7 +223,7 @@ export const fetchDocs = createServerFn({ method: 'GET' })
223223
const file = await readRepoFileOrFallback(repo, branch, filePath)
224224

225225
if (!file) {
226-
throw notFound()
226+
throw createDocsNotFoundError()
227227
}
228228

229229
const frontMatter = extractFrontMatter(file)
@@ -267,7 +267,7 @@ export const fetchFile = createServerFn({ method: 'GET' })
267267
const file = await readRepoFileOrFallback(repo, branch, filePath)
268268

269269
if (!file) {
270-
throw notFound()
270+
throw createDocsNotFoundError()
271271
}
272272

273273
setDocsCacheHeaders('max-age=3600, stale-while-revalidate=3600, durable')
@@ -284,7 +284,7 @@ export const fetchRepoDirectoryContents = createServerFn({
284284
const githubContents = await fetchApiContents(repo, branch, startingPath)
285285

286286
if (!githubContents) {
287-
throw notFound()
287+
throw createDocsNotFoundError()
288288
}
289289

290290
setDocsCacheHeaders('max-age=3600, stale-while-revalidate=3600, durable')

src/utils/docs.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { notFound } from '@tanstack/react-router'
21
import {
32
fetchDocs,
43
fetchDocsPage,
@@ -7,6 +6,7 @@ import {
76
fetchFile,
87
fetchRepoDirectoryContents,
98
} from './docs.functions'
9+
import { createDocsNotFoundError } from './docs-errors'
1010
import { removeLeadingSlash } from './utils'
1111

1212
export const loadDocs = async ({
@@ -21,11 +21,7 @@ export const loadDocs = async ({
2121
docsPath: string
2222
}) => {
2323
if (!branch || !docsRoot || !docsPath) {
24-
throw notFound({
25-
data: {
26-
message: 'No doc was found here!',
27-
},
28-
})
24+
throw createDocsNotFoundError()
2925
}
3026

3127
return fetchDocs({
@@ -49,11 +45,7 @@ export const loadDocsPage = async ({
4945
docsPath: string
5046
}) => {
5147
if (!branch || !docsRoot || !docsPath) {
52-
throw notFound({
53-
data: {
54-
message: 'No doc was found here!',
55-
},
56-
})
48+
throw createDocsNotFoundError()
5749
}
5850

5951
return fetchDocsPage({

0 commit comments

Comments
 (0)