Skip to content

Commit

Permalink
feature: add error handling when stats file is outdated
Browse files Browse the repository at this point in the history
  • Loading branch information
byCedric committed Mar 12, 2024
1 parent edbc659 commit c72ca19
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
19 changes: 17 additions & 2 deletions src/cli/bin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node
import arg from 'arg';
import open from 'open';
import path from 'path';

import { resolveOptions } from './resolveOptions';
import { createServer } from './server';
Expand Down Expand Up @@ -39,8 +40,6 @@ if (args['--help']) {
process.on('SIGINT', () => process.exit(0));
process.on('SIGTERM', () => process.exit(0));

run();

async function run() {
const options = await resolveOptions(args);
const server = createServer(options);
Expand All @@ -54,3 +53,19 @@ async function run() {
open(href);
});
}

run().catch((error) => {
if (error.type !== 'AtlasError') {
throw error;
}

if (error.code === 'STATS_FILE_INCOMPATIBLE') {
const statsFile = path.relative(process.cwd(), error.statsFile);
console.error('Stats file is incompatible with this version, use this instead:');
console.error(` npx expo-atlas@${error.incompatibleVersion} ${statsFile}`);
} else {
console.error(`${error.message} (${error.code})`);
}

process.exit(1);
});
6 changes: 1 addition & 5 deletions src/cli/resolveOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ async function resolveStatsFile(input: Input) {
throw new Error(`Could not find stats file "${statsFile}".`);
}

try {
await validateStatsFile(statsFile);
} catch (error) {
throw new Error(`Stats file is incompatible with this version.`, { cause: error });
}
await validateStatsFile(statsFile);

return path.resolve(statsFile);
}
Expand Down
5 changes: 3 additions & 2 deletions src/metro/serializeStatsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path';
import { type MetroStatsEntry } from './convertGraphToStats';
import { name, version } from '../../package.json';
import { env } from '../utils/env';
import { AtlasValidationError } from '../utils/errors';
import { mapLines, readFirstLine, readLine } from '../utils/file';

export type StatsMetadata = { name: string; version: string };
Expand All @@ -21,7 +22,7 @@ export function getStatsMetdata(): StatsMetadata {
/** Validate if the stats file is compatible with this library version */
export async function validateStatsFile(statsFile: string, metadata = getStatsMetdata()) {
if (!fs.existsSync(statsFile)) {
throw new Error(`Stats file "${statsFile}" not found.`);
throw new AtlasValidationError('STATS_FILE_NOT_FOUND', statsFile);
}

if (env.EXPO_NO_STATS_VALIDATION) {
Expand All @@ -32,7 +33,7 @@ export async function validateStatsFile(statsFile: string, metadata = getStatsMe
const data = line ? JSON.parse(line) : {};

if (data.name !== metadata.name || data.version !== metadata.version) {
throw new Error(`Stats file "${statsFile}" is incompatible with this version of the plugin.`);
throw new AtlasValidationError('STATS_FILE_INCOMPATIBLE', statsFile, data.version);
}
}

Expand Down
38 changes: 38 additions & 0 deletions src/utils/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export class AtlasError extends Error {
/** A property to determine if any of the extended errors are atlas-specific errors */
public readonly type = 'AtlasError';
/** The error (class) name */
public readonly name: string;
/** The error code, specifically for these types of errors */
public readonly code?: string;

constructor(code: string, message = '', options?: ErrorOptions) {
super(message, options);
this.name = this.constructor.name;
this.code = code;
}
}

export class AtlasValidationError extends AtlasError {
constructor(
code: 'STATS_FILE_NOT_FOUND' | 'STATS_FILE_INCOMPATIBLE',
public readonly statsFile: string,
public readonly incompatibleVersion?: string
) {
super(
code,
code === 'STATS_FILE_NOT_FOUND'
? `Stats file not found: ${statsFile}`
: `Stats file is incompatible with this version.`
);
}
}

export function handleError(error: Error) {
if (error instanceof AtlasError) {
console.error(`${error.message} (${error.code})`);
return true;
}

throw error;
}

0 comments on commit c72ca19

Please sign in to comment.