Skip to content

Commit d58c1ce

Browse files
Nikola-3ngrujic
and
ngrujic
authored
Handle invalid clockspec error and log more when loading cache fails (#9709)
* catch any error during reading request graph and log snapshot file in case watchman fails reading it * log clockspec and other errors separately * remove redundant if check * use existing snapshot path * clean up commit * extract new logging to function --------- Co-authored-by: ngrujic <[email protected]>
1 parent fa4bb34 commit d58c1ce

File tree

1 file changed

+71
-36
lines changed

1 file changed

+71
-36
lines changed

packages/core/core/src/RequestTracker.js

+71-36
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ export const requestGraphEdgeTypes = {
6565
dirname: 7,
6666
};
6767

68+
class FSBailoutError extends Error {
69+
name: string = 'FSBailoutError';
70+
}
71+
6872
export type RequestGraphEdgeType = $Values<typeof requestGraphEdgeTypes>;
6973

7074
type RequestGraphOpts = {|
@@ -855,7 +859,7 @@ export class RequestGraph extends ContentGraph<
855859
predictedTime,
856860
},
857861
});
858-
throw new Error(
862+
throw new FSBailoutError(
859863
'Responding to file system events exceeded threshold, start with empty cache.',
860864
);
861865
}
@@ -1543,55 +1547,58 @@ async function loadRequestGraph(options): Async<RequestGraph> {
15431547

15441548
let cacheKey = getCacheKey(options);
15451549
let requestGraphKey = `requestGraph-${cacheKey}`;
1546-
1550+
let timeout;
1551+
const snapshotKey = `snapshot-${cacheKey}`;
1552+
const snapshotPath = path.join(options.cacheDir, snapshotKey + '.txt');
15471553
if (await options.cache.hasLargeBlob(requestGraphKey)) {
1548-
let {requestGraph} = await readAndDeserializeRequestGraph(
1549-
options.cache,
1550-
requestGraphKey,
1551-
cacheKey,
1552-
);
1554+
try {
1555+
let {requestGraph} = await readAndDeserializeRequestGraph(
1556+
options.cache,
1557+
requestGraphKey,
1558+
cacheKey,
1559+
);
15531560

1554-
let opts = getWatcherOptions(options);
1555-
let snapshotKey = `snapshot-${cacheKey}`;
1556-
let snapshotPath = path.join(options.cacheDir, snapshotKey + '.txt');
1561+
let opts = getWatcherOptions(options);
1562+
1563+
timeout = setTimeout(() => {
1564+
logger.warn({
1565+
origin: '@parcel/core',
1566+
message: `Retrieving file system events since last build...\nThis can take upto a minute after branch changes or npm/yarn installs.`,
1567+
});
1568+
}, 5000);
1569+
let startTime = Date.now();
1570+
let events = await options.inputFS.getEventsSince(
1571+
options.watchDir,
1572+
snapshotPath,
1573+
opts,
1574+
);
1575+
clearTimeout(timeout);
15571576

1558-
let timeout = setTimeout(() => {
1559-
logger.warn({
1577+
logger.verbose({
15601578
origin: '@parcel/core',
1561-
message: `Retrieving file system events since last build...\nThis can take upto a minute after branch changes or npm/yarn installs.`,
1579+
message: `File system event count: ${events.length}`,
1580+
meta: {
1581+
trackableEvent: 'watcher_events_count',
1582+
watcherEventCount: events.length,
1583+
duration: Date.now() - startTime,
1584+
},
15621585
});
1563-
}, 5000);
1564-
let startTime = Date.now();
1565-
let events = await options.inputFS.getEventsSince(
1566-
options.watchDir,
1567-
snapshotPath,
1568-
opts,
1569-
);
1570-
clearTimeout(timeout);
1571-
1572-
logger.verbose({
1573-
origin: '@parcel/core',
1574-
message: `File system event count: ${events.length}`,
1575-
meta: {
1576-
trackableEvent: 'watcher_events_count',
1577-
watcherEventCount: events.length,
1578-
duration: Date.now() - startTime,
1579-
},
1580-
});
15811586

1582-
requestGraph.invalidateUnpredictableNodes();
1583-
requestGraph.invalidateOnBuildNodes();
1584-
requestGraph.invalidateEnvNodes(options.env);
1585-
requestGraph.invalidateOptionNodes(options);
1587+
requestGraph.invalidateUnpredictableNodes();
1588+
requestGraph.invalidateOnBuildNodes();
1589+
requestGraph.invalidateEnvNodes(options.env);
1590+
requestGraph.invalidateOptionNodes(options);
15861591

1587-
try {
15881592
await requestGraph.respondToFSEvents(
15891593
options.unstableFileInvalidations || events,
15901594
options,
15911595
10000,
15921596
);
15931597
return requestGraph;
15941598
} catch (e) {
1599+
// Prevent logging fs events took too long warning
1600+
clearTimeout(timeout);
1601+
logErrorOnBailout(options, snapshotPath, e);
15951602
// This error means respondToFSEvents timed out handling the invalidation events
15961603
// In this case we'll return a fresh RequestGraph
15971604
return new RequestGraph();
@@ -1600,3 +1607,31 @@ async function loadRequestGraph(options): Async<RequestGraph> {
16001607

16011608
return new RequestGraph();
16021609
}
1610+
function logErrorOnBailout(
1611+
options: ParcelOptions,
1612+
snapshotPath: string,
1613+
e: Error,
1614+
): void {
1615+
if (e.message && e.message.includes('invalid clockspec')) {
1616+
const snapshotContents = options.inputFS.readFileSync(
1617+
snapshotPath,
1618+
'utf-8',
1619+
);
1620+
logger.warn({
1621+
origin: '@parcel/core',
1622+
message: `Error reading clockspec from snapshot, building with clean cache.`,
1623+
meta: {
1624+
snapshotContents: snapshotContents,
1625+
trackableEvent: 'invalid_clockspec_error',
1626+
},
1627+
});
1628+
} else if (!(e instanceof FSBailoutError)) {
1629+
logger.warn({
1630+
origin: '@parcel/core',
1631+
message: `Unexpected error loading cache from disk, building with clean cache.`,
1632+
meta: {
1633+
trackableEvent: 'cache_load_error',
1634+
},
1635+
});
1636+
}
1637+
}

0 commit comments

Comments
 (0)