diff --git a/src/util/file_reader.ts b/src/util/file_reader.ts index 284f0dd8..105ee8b1 100644 --- a/src/util/file_reader.ts +++ b/src/util/file_reader.ts @@ -72,7 +72,7 @@ async function collectGitBehaviors(gitUrl: string): Promise { ); return await collectLocalPathBehaviors(pathToCollect); } catch (e) { - logger.error( + logger.fatal( "Error downloading custom behaviors from Git repo", { url: urlStripped, error: e }, "behavior", @@ -96,7 +96,7 @@ async function collectOnlineBehavior(url: string): Promise { ); return await collectLocalPathBehaviors(behaviorFilepath); } catch (e) { - logger.error( + logger.fatal( "Error downloading custom behavior from URL", { url, error: e }, "behavior", @@ -120,37 +120,56 @@ async function collectLocalPathBehaviors( return []; } - const stat = await fsp.stat(resolvedPath); - - if (stat.isFile() && ALLOWED_EXTS.includes(path.extname(resolvedPath))) { - const contents = await fsp.readFile(resolvedPath); - return [ - { - path: resolvedPath, - contents: `/* src: ${resolvedPath} */\n\n${contents}`, - }, - ]; - } - const behaviors: FileSources = []; - const isDir = stat.isDirectory(); + try { + const stat = await fsp.stat(resolvedPath); - if (!isDir && depth === 0) { - logger.warn( - "The provided path is not a .js file or directory", - { path: resolvedPath }, + if (stat.isFile() && ALLOWED_EXTS.includes(path.extname(resolvedPath))) { + const contents = await fsp.readFile(resolvedPath); + return [ + { + path: resolvedPath, + contents: `/* src: ${resolvedPath} */\n\n${contents}`, + }, + ]; + } + + const isDir = stat.isDirectory(); + + if (!isDir && depth === 0) { + logger.warn( + "The provided path is not a .js file or directory", + { path: resolvedPath }, + "behavior", + ); + } + + if (isDir) { + const files = await fsp.readdir(resolvedPath); + for (const file of files) { + const filePath = path.join(resolvedPath, file); + const newBehaviors = await collectLocalPathBehaviors( + filePath, + depth + 1, + ); + behaviors.push(...newBehaviors); + } + } + } catch (e) { + logger.fatal( + "Error fetching local custom behaviors", + { path: resolvedPath, error: e }, "behavior", ); } - if (isDir) { - const files = await fsp.readdir(resolvedPath); - for (const file of files) { - const filePath = path.join(resolvedPath, file); - const newBehaviors = await collectLocalPathBehaviors(filePath, depth + 1); - behaviors.push(...newBehaviors); - } + if (!behaviors && depth === 0) { + logger.fatal( + "No custom behaviors found at specified path", + { path: resolvedPath }, + "behavior", + ); } return behaviors; diff --git a/tests/custom-behavior.test.js b/tests/custom-behavior.test.js index 0e2249d0..3bd8795d 100644 --- a/tests/custom-behavior.test.js +++ b/tests/custom-behavior.test.js @@ -120,3 +120,48 @@ test("test invalid behavior exit", async () => { // logger fatal exit code expect(status).toBe(17); }); + +test("test crawl exits if behavior not fetched from url", async () => { + let status = 0; + + try { + child_process.execSync( + "docker run -v $PWD/test-crawls:/crawls webrecorder/browsertrix-crawler crawl --url https://example.com --customBehaviors https://webrecorder.net/doesntexist/custombehavior.js --scopeType page", + ); + } catch (e) { + status = e.status; + } + + // logger fatal exit code + expect(status).toBe(17); +}); + +test("test crawl exits if behavior not fetched from git repo", async () => { + let status = 0; + + try { + child_process.execSync( + "docker run -v $PWD/test-crawls:/crawls webrecorder/browsertrix-crawler crawl --url https://example.com --customBehaviors git+https://github.com/webrecorder/doesntexist --scopeType page", + ); + } catch (e) { + status = e.status; + } + + // logger fatal exit code + expect(status).toBe(17); +}); + +test("test crawl exits if not custom behaviors collected from local path", async () => { + let status = 0; + + try { + child_process.execSync( + "docker run -v $PWD/test-crawls:/crawls webrecorder/browsertrix-crawler crawl --url https://example.com --customBehaviors /custom-behaviors/doesntexist --scopeType page", + ); + } catch (e) { + status = e.status; + } + + // logger fatal exit code + expect(status).toBe(17); +});