Skip to content

Commit 3b28a99

Browse files
authored
fix: createAssets fails in case of broken JSON in fetch cache (#963)
* fix: createAssets fails in case of broken JSON in fetch cache * Add changeset * Fix bump up from major to patch * Log information about incorrectly parsed file * Fix remarks to PR, adjust logging * Fix code review remark * Fix linting
1 parent 05e911f commit 3b28a99

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

.changeset/popular-tomatoes-jog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opennextjs/aws": patch
3+
---
4+
5+
fix: createAssets fails in case of broken JSON in fetch cache

packages/open-next/src/build/createAssets.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from "node:fs";
22
import path from "node:path";
33

44
import { loadConfig } from "config/util.js";
5+
import { safeParseJsonFile } from "utils/safe-json-parse.js";
56
import logger from "../logger.js";
67
import type { TagCacheMetaFile } from "../types/cache.js";
78
import { isBinaryContentType } from "../utils/binary.js";
@@ -159,15 +160,20 @@ export function createCacheAssets(options: buildHelper.BuildOptions) {
159160
// Generate cache file
160161
Object.entries(cacheFilesPath).forEach(([cacheFilePath, files]) => {
161162
const cacheFileMeta = files.meta
162-
? JSON.parse(fs.readFileSync(files.meta, "utf8"))
163+
? safeParseJsonFile(fs.readFileSync(files.meta, "utf8"), cacheFilePath)
163164
: undefined;
165+
const cacheJson = files.json
166+
? safeParseJsonFile(fs.readFileSync(files.json, "utf8"), cacheFilePath)
167+
: undefined;
168+
if ((files.meta && !cacheFileMeta) || (files.json && !cacheJson)) {
169+
logger.warn(`Skipping invalid cache file: ${cacheFilePath}`);
170+
return;
171+
}
164172
const cacheFileContent = {
165173
type: files.body ? "route" : files.json ? "page" : "app",
166174
meta: cacheFileMeta,
167175
html: files.html ? fs.readFileSync(files.html, "utf8") : undefined,
168-
json: files.json
169-
? JSON.parse(fs.readFileSync(files.json, "utf8"))
170-
: undefined,
176+
json: cacheJson,
171177
rsc: files.rsc ? fs.readFileSync(files.rsc, "utf8") : undefined,
172178
body: files.body
173179
? fs
@@ -203,7 +209,7 @@ export function createCacheAssets(options: buildHelper.BuildOptions) {
203209
() => true,
204210
({ absolutePath, relativePath }) => {
205211
const fileContent = fs.readFileSync(absolutePath, "utf8");
206-
const fileData = JSON.parse(fileContent);
212+
const fileData = safeParseJsonFile(fileContent, absolutePath);
207213
fileData?.tags?.forEach((tag: string) => {
208214
metaFiles.push({
209215
tag: { S: path.posix.join(buildId, tag) },
@@ -227,8 +233,8 @@ export function createCacheAssets(options: buildHelper.BuildOptions) {
227233
absolutePath.endsWith(".meta") && !isFileSkipped(relativePath),
228234
({ absolutePath, relativePath }) => {
229235
const fileContent = fs.readFileSync(absolutePath, "utf8");
230-
const fileData = JSON.parse(fileContent);
231-
if (fileData.headers?.["x-next-cache-tags"]) {
236+
const fileData = safeParseJsonFile(fileContent, absolutePath);
237+
if (fileData?.headers?.["x-next-cache-tags"]) {
232238
fileData.headers["x-next-cache-tags"]
233239
.split(",")
234240
.forEach((tag: string) => {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import logger from "../logger.js";
2+
3+
export function safeParseJsonFile<T = any>(
4+
input: string,
5+
filePath: string,
6+
fallback?: T,
7+
): T | undefined {
8+
try {
9+
return JSON.parse(input);
10+
} catch (err) {
11+
logger.warn(
12+
`Failed to parse JSON file "${filePath}". Error: ${(err as Error).message}`,
13+
);
14+
return fallback;
15+
}
16+
}

0 commit comments

Comments
 (0)