Skip to content

Commit 52f3130

Browse files
committed
refactor(isolation): share worker error inspection
1 parent d998f66 commit 52f3130

2 files changed

Lines changed: 22 additions & 27 deletions

File tree

src/copy-containment.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ function containmentError(
5959
return error;
6060
}
6161

62-
function errorCode(error: unknown): string | null {
63-
if (typeof error === 'object' && error !== null && 'code' in error) {
62+
export function isCopyRecord(value: unknown): value is Record<PropertyKey, unknown> {
63+
return typeof value === 'object' && value !== null;
64+
}
65+
66+
export function copyErrorCode(error: unknown): string | null {
67+
if (isCopyRecord(error) && 'code' in error) {
6468
return typeof error.code === 'string' ? error.code : null;
6569
}
6670
return null;
@@ -153,7 +157,7 @@ export function resolveSourcePath(boundary: CopyBoundary, relativePath: string):
153157
try {
154158
canonicalPath = fs.realpathSync.native(candidatePath);
155159
} catch (error: unknown) {
156-
if (errorCode(error) === 'ELOOP') {
160+
if (copyErrorCode(error) === 'ELOOP') {
157161
throw containmentError(relativePath, 'source path contains a symlink cycle', error);
158162
}
159163
throw error;
@@ -180,7 +184,7 @@ function resolveDestinationPath(boundary: CopyBoundary, relativePath: string): s
180184
fs.lstatSync(candidatePath);
181185
existingPath = candidatePath;
182186
} catch (error: unknown) {
183-
if (errorCode(error) !== 'ENOENT') {
187+
if (copyErrorCode(error) !== 'ENOENT') {
184188
throw error;
185189
}
186190
// The copy pipeline creates directories parent-first in phase two, so the
@@ -231,12 +235,7 @@ export function resolveCopyPath(
231235
}
232236

233237
export function isCopyContainmentError(error: unknown): boolean {
234-
return (
235-
typeof error === 'object' &&
236-
error !== null &&
237-
'code' in error &&
238-
error.code === CONTAINMENT_ERROR_CODE
239-
);
238+
return isCopyRecord(error) && error.code === CONTAINMENT_ERROR_CODE;
240239
}
241240

242241
interface CopyErrorPayload {

src/copy-worker.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
*/
77
import fs = require('fs');
88
import { parentPort, workerData } from 'worker_threads';
9-
import { createCopyBoundary, isCopyContainmentError, resolveCopyPath } from './copy-containment';
9+
import {
10+
copyErrorCode,
11+
createCopyBoundary,
12+
isCopyContainmentError,
13+
isCopyRecord,
14+
resolveCopyPath,
15+
} from './copy-containment';
1016
import type { CopyBoundary } from './copy-containment';
1117
interface CopyWorkerData {
1218
files: string[];
@@ -22,27 +28,17 @@ interface CopyError {
2228
relativePath: unknown;
2329
}
2430
function isCopyWorkerData(value: unknown): value is CopyWorkerData {
31+
if (!isCopyRecord(value)) {
32+
return false;
33+
}
2534
return (
26-
typeof value === 'object' &&
27-
value !== null &&
28-
'files' in value &&
2935
Array.isArray(value.files) &&
3036
value.files.every((entry: unknown) => typeof entry === 'string') &&
31-
'sourceBase' in value &&
3237
typeof value.sourceBase === 'string' &&
33-
'destBase' in value &&
3438
typeof value.destBase === 'string' &&
35-
'expectedBoundary' in value &&
36-
typeof value.expectedBoundary === 'object' &&
37-
value.expectedBoundary !== null
39+
isCopyRecord(value.expectedBoundary)
3840
);
3941
}
40-
function errorCode(error: unknown): string | null {
41-
if (typeof error === 'object' && error !== null && 'code' in error) {
42-
return typeof error.code === 'string' ? error.code : null;
43-
}
44-
return null;
45-
}
4642
function errorMessage(error: unknown): string {
4743
return error instanceof Error ? error.message : String(error);
4844
}
@@ -64,7 +60,7 @@ for (const relativePath of files) {
6460
copied++;
6561
} catch (caughtError: unknown) {
6662
// Skip files we can't copy (permission denied, broken symlinks, etc.)
67-
const code = errorCode(caughtError);
63+
const code = copyErrorCode(caughtError);
6864
if (
6965
!isCopyContainmentError(caughtError) &&
7066
(code === 'EACCES' || code === 'EPERM' || code === 'ENOENT')
@@ -78,7 +74,7 @@ for (const relativePath of files) {
7874
code,
7975
message: errorMessage(caughtError),
8076
relativePath:
81-
typeof caughtError === 'object' && caughtError !== null && 'relativePath' in caughtError
77+
isCopyRecord(caughtError) && 'relativePath' in caughtError
8278
? caughtError.relativePath
8379
: relativePath,
8480
};

0 commit comments

Comments
 (0)