Skip to content

Commit 37b224a

Browse files
authoredFeb 15, 2024··
Fix missing api/auth, api/guides pages (#9153)
The `api/auth` route added for the changelog conflicts with the `api/auth` docs page that would normally be handled by the catchall `[[...path]]` route. Move it under the `changelog` path to fix the route conflict. Even so, the pages continued to 404. Commit 680c7c4 added memoized the fetch for OpenAPI JSON in the `resolveOpenAPI` function, but that particular implementation caused some problems with the build output. Some of the pages in the API section went missing. The previous implementation was susceptible to a bit of a race condition, since the cached value wasn't set until after several async calls. When Next tries to aggressively build pages, multiple calls could have gotten through to do live calls, and then all of them would have tried to set the cache variable. I don't know the exact pathway to the issue but I suspect this had something to do with the missing pages (some sort of data corruption?). Sorry, I know this is handwavy. Anyway, replacing that implementation with a more robust one - one that caches a promise on the first call, and reuses that promise on all future calls - will definitely only fetch once per process. When the fetch completes, everyone waiting on the promise will awaken, and then future callers of the method will get a resolved promise for immediate results. And, most importantly, this method of caching doesn't cause the `api/auth` and `api/guides` pages to go missing.
1 parent 5dae0d5 commit 37b224a

File tree

6 files changed

+18
-18
lines changed

6 files changed

+18
-18
lines changed
 

‎app/changelog/%5Fadmin/layout.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {type ReactNode, Suspense} from 'react';
2-
import {GET} from 'app/api/auth/[...nextauth]/route';
2+
import {GET} from 'app/changelog/api/auth/[...nextauth]/route';
33
import {getServerSession} from 'next-auth/next';
44

55
import LoginButton from 'sentry-docs/components/changelog/loginButton';

‎app/changelog/%5Fadmin/upload/route.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import crypto from 'crypto';
22

33
import {Storage} from '@google-cloud/storage';
4-
import {GET as sessionHandler} from 'app/api/auth/[...nextauth]/route';
4+
import {GET as sessionHandler} from 'app/changelog/api/auth/[...nextauth]/route';
55
import {NextRequest} from 'next/server';
66
import {getServerSession} from 'next-auth/next';
77

‎app/changelog/[slug]/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {Fragment, Suspense} from 'react';
22
import {type Category, type Changelog} from '@prisma/client';
33
import * as Sentry from '@sentry/nextjs';
4-
import {GET} from 'app/api/auth/[...nextauth]/route';
4+
import {GET} from 'app/changelog/api/auth/[...nextauth]/route';
55
import type {Metadata, ResolvingMetadata} from 'next';
66
import Link from 'next/link';
77
import {getServerSession} from 'next-auth/next';

‎src/actions/changelog.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use server';
22

3-
import {GET as handler} from 'app/api/auth/[...nextauth]/route';
3+
import {GET as handler} from 'app/changelog/api/auth/[...nextauth]/route';
44
import {revalidatePath} from 'next/cache';
55
import {redirect} from 'next/navigation';
66
import {getServerSession} from 'next-auth/next';

‎src/build/resolveOpenAPI.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
import {promises as fs} from 'fs';
66

7-
import {cache} from 'react';
8-
97
import {DeRefedOpenAPI} from './open-api/types';
108

119
// SENTRY_API_SCHEMA_SHA is used in the sentry-docs GHA workflow in getsentry/sentry-api-schema.
@@ -14,8 +12,6 @@ const SENTRY_API_SCHEMA_SHA = '78a8da372a1912d69e27b7f36603017cd29b6815';
1412

1513
const activeEnv = process.env.GATSBY_ENV || process.env.NODE_ENV || 'development';
1614

17-
let cachedResonse: DeRefedOpenAPI | null = null;
18-
1915
async function resolveOpenAPI(): Promise<DeRefedOpenAPI> {
2016
if (activeEnv === 'development' && process.env.OPENAPI_LOCAL_PATH) {
2117
try {
@@ -29,16 +25,10 @@ async function resolveOpenAPI(): Promise<DeRefedOpenAPI> {
2925
);
3026
}
3127
}
32-
33-
if (cachedResonse) {
34-
return cachedResonse;
35-
}
3628
const response = await fetch(
37-
`https://raw.githubusercontent.com/getsentry/sentry-api-schema/${SENTRY_API_SCHEMA_SHA}/openapi-derefed.json`,
38-
{cache: 'no-store'}
29+
`https://raw.githubusercontent.com/getsentry/sentry-api-schema/${SENTRY_API_SCHEMA_SHA}/openapi-derefed.json`
3930
);
40-
cachedResonse = await response.json();
41-
return cachedResonse!;
31+
return await response.json();
4232
}
4333

4434
export type APIParameter = {
@@ -85,7 +75,17 @@ function slugify(s: string): string {
8575
.toLowerCase();
8676
}
8777

88-
export const apiCategories = cache(async (): Promise<APICategory[]> => {
78+
let apiCategoriesCache: Promise<APICategory[]> | undefined;
79+
80+
export function apiCategories(): Promise<APICategory[]> {
81+
if (apiCategoriesCache) {
82+
return apiCategoriesCache;
83+
}
84+
apiCategoriesCache = apiCategoriesUncached();
85+
return apiCategoriesCache;
86+
}
87+
88+
async function apiCategoriesUncached(): Promise<APICategory[]> {
8989
const data = await resolveOpenAPI();
9090

9191
const categoryMap: {[name: string]: APICategory} = {};
@@ -150,7 +150,7 @@ export const apiCategories = cache(async (): Promise<APICategory[]> => {
150150
c.apis.sort((a, b) => a.name.localeCompare(b.name));
151151
});
152152
return categories;
153-
});
153+
}
154154

155155
function getBodyParameters(apiData): APIParameter[] {
156156
const content = apiData.requestBody?.content;

0 commit comments

Comments
 (0)
Please sign in to comment.