Skip to content

Commit

Permalink
exit code cleanup (#753)
Browse files Browse the repository at this point in the history
- use consistent enums for exit codes
- add disk space check on startup and add OutOfSpace exit code (3)
- preparation for #584
  • Loading branch information
ikreymer authored Feb 7, 2025
1 parent b435afe commit 5c9d808
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 22 deletions.
32 changes: 24 additions & 8 deletions src/crawler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
interpolateFilename,
checkDiskUtilization,
S3StorageSync,
isDiskFull,
} from "./util/storage.js";
import { ScreenCaster, WSTransport } from "./util/screencaster.js";
import { Screenshots } from "./util/screenshots.js";
Expand All @@ -46,6 +47,7 @@ import {
ExtractSelector,
PAGE_OP_TIMEOUT_SECS,
SITEMAP_INITIAL_FETCH_TIMEOUT_SECS,
ExitCodes,
} from "./util/constants.js";

import { AdBlockRules, BlockRuleDecl, BlockRules } from "./util/blockrules.js";
Expand Down Expand Up @@ -462,6 +464,15 @@ export class Crawler {
}

async bootstrap() {
if (await isDiskFull(this.params.cwd)) {
logger.fatal(
"Out of disk space, exiting",
{},
"general",
ExitCodes.OutOfSpace,
);
}

const subprocesses: ChildProcess[] = [];

const redisUrl = this.params.redisStoreUrl || "redis://localhost:6379/0";
Expand Down Expand Up @@ -572,7 +583,7 @@ export class Crawler {
await this.bootstrap();

let status = "done";
let exitCode = 0;
let exitCode = ExitCodes.Success;

try {
await this.crawl();
Expand All @@ -587,12 +598,14 @@ export class Crawler {
logger.info("Crawl gracefully stopped on request");
} else if (this.interrupted) {
status = "interrupted";
exitCode = this.browserCrashed ? 10 : 11;
exitCode = this.browserCrashed
? ExitCodes.BrowserCrashed
: ExitCodes.InterruptedGraceful;
}
}
} catch (e) {
logger.error("Crawl failed", e);
exitCode = 9;
exitCode = ExitCodes.Failed;
status = "failing";
if (await this.crawlState.incFailCount()) {
status = "failed";
Expand Down Expand Up @@ -1419,11 +1432,11 @@ self.__bx_behaviors.selectMainBehavior();

async checkCanceled() {
if (this.crawlState && (await this.crawlState.isCrawlCanceled())) {
await this.setStatusAndExit(0, "canceled");
await this.setStatusAndExit(ExitCodes.Success, "canceled");
}
}

async setStatusAndExit(exitCode: number, status: string) {
async setStatusAndExit(exitCode: ExitCodes, status: string) {
logger.info(`Exiting, Crawl status: ${status}`);

await this.closeLog();
Expand All @@ -1442,11 +1455,14 @@ self.__bx_behaviors.selectMainBehavior();
await closeWorkers(0);
await this.closeFiles();
if (!this.done) {
await this.setStatusAndExit(13, "interrupted");
await this.setStatusAndExit(
ExitCodes.InterruptedImmediate,
"interrupted",
);
return;
}
}
await this.setStatusAndExit(0, "done");
await this.setStatusAndExit(ExitCodes.Success, "done");
}

async isCrawlRunning() {
Expand All @@ -1455,7 +1471,7 @@ self.__bx_behaviors.selectMainBehavior();
}

if (await this.crawlState.isCrawlCanceled()) {
await this.setStatusAndExit(0, "canceled");
await this.setStatusAndExit(ExitCodes.Success, "canceled");
return false;
}

Expand Down
15 changes: 9 additions & 6 deletions src/create-login-profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Browser } from "./util/browser.js";
import { initStorage } from "./util/storage.js";
import { CDPSession, Page, PuppeteerLifeCycleEvent } from "puppeteer-core";
import { getInfoString } from "./util/file_reader.js";
import { DISPLAY } from "./util/constants.js";
import { DISPLAY, ExitCodes } from "./util/constants.js";
import { initProxy } from "./util/proxy.js";
//import { sleep } from "./util/timing.js";

Expand Down Expand Up @@ -147,7 +147,7 @@ function getDefaultWindowSize() {

function handleTerminate(signame: string) {
logger.info(`Got signal ${signame}, exiting`);
process.exit(1);
process.exit(ExitCodes.GenericError);
}

async function main() {
Expand Down Expand Up @@ -478,7 +478,10 @@ class InteractiveBrowser {
this.shutdownWait = params.shutdownWait * 1000;

if (this.shutdownWait) {
this.shutdownTimer = setTimeout(() => process.exit(0), this.shutdownWait);
this.shutdownTimer = setTimeout(
() => process.exit(ExitCodes.Success),
this.shutdownWait,
);
logger.debug(
`Shutting down in ${this.shutdownWait}ms if no ping received`,
);
Expand Down Expand Up @@ -602,7 +605,7 @@ class InteractiveBrowser {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
clearTimeout(this.shutdownTimer as any);
this.shutdownTimer = setTimeout(
() => process.exit(0),
() => process.exit(ExitCodes.Success),
this.shutdownWait,
);
logger.debug(
Expand Down Expand Up @@ -682,7 +685,7 @@ class InteractiveBrowser {
logger.warn("HTTP Error", e);
}

setTimeout(() => process.exit(0), 200);
setTimeout(() => process.exit(ExitCodes.Success), 200);
return;

case "/createProfile":
Expand All @@ -708,7 +711,7 @@ class InteractiveBrowser {
logger.warn("HTTP Error", e);
}

setTimeout(() => process.exit(0), 200);
setTimeout(() => process.exit(ExitCodes.Success), 200);
return;
}

Expand Down
5 changes: 3 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { setExitOnRedisError } from "./util/redis.js";
import { Crawler } from "./crawler.js";
import { ReplayCrawler } from "./replaycrawler.js";
import fs from "node:fs";
import { ExitCodes } from "./util/constants.js";

let crawler: Crawler | null = null;

Expand All @@ -15,12 +16,12 @@ async function handleTerminate(signame: string) {
logger.info(`${signame} received...`);
if (!crawler || !crawler.crawlState) {
logger.error("error: no crawler running, exiting");
process.exit(1);
process.exit(ExitCodes.GenericError);
}

if (crawler.done) {
logger.info("success: crawler done, exiting");
process.exit(0);
process.exit(ExitCodes.Success);
}

setExitOnRedisError();
Expand Down
12 changes: 12 additions & 0 deletions src/util/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ export const BEHAVIOR_TYPES = [
];

export const DISPLAY = ":99";

export enum ExitCodes {
Success = 0,
GenericError = 1,
Failed = 9,
OutOfSpace = 3,
BrowserCrashed = 10,
InterruptedGraceful = 11,
InterruptedImmediate = 13,
Fatal = 17,
ProxyError = 21,
}
13 changes: 9 additions & 4 deletions src/util/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { Writable } from "node:stream";
import { RedisCrawlState } from "./state.js";
import { ExitCodes } from "./constants.js";

// RegExp.prototype.toJSON = RegExp.prototype.toString;
Object.defineProperty(RegExp.prototype, "toJSON", {
Expand Down Expand Up @@ -73,7 +74,7 @@ class Logger {
contexts: LogContext[] = [];
excludeContexts: LogContext[] = [];
crawlState?: RedisCrawlState | null = null;
fatalExitCode = 17;
fatalExitCode: ExitCodes = ExitCodes.Fatal;

setDefaultFatalExitCode(exitCode: number) {
this.fatalExitCode = exitCode;
Expand Down Expand Up @@ -143,8 +144,12 @@ class Logger {
};
const string = JSON.stringify(dataToLog);
console.log(string);
if (this.logStream) {
this.logStream.write(string + "\n");
try {
if (this.logStream) {
this.logStream.write(string + "\n");
}
} catch (e) {
//
}

const toLogToRedis = ["error", "fatal"];
Expand Down Expand Up @@ -179,7 +184,7 @@ class Logger {
message: string,
data = {},
context: LogContext = "general",
exitCode = 0,
exitCode = ExitCodes.Success,
) {
exitCode = exitCode || this.fatalExitCode;
this.logAsJSON(`${message}. Quitting`, data, context, "fatal");
Expand Down
4 changes: 2 additions & 2 deletions src/util/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { logger } from "./logger.js";

import { socksDispatcher } from "fetch-socks";
import type { SocksProxyType } from "socks/typings/common/constants.js";
import { FETCH_HEADERS_TIMEOUT_SECS } from "./constants.js";
import { ExitCodes, FETCH_HEADERS_TIMEOUT_SECS } from "./constants.js";

const SSH_PROXY_LOCAL_PORT = 9722;

Expand Down Expand Up @@ -194,7 +194,7 @@ export async function runSSHD(params: Record<string, any>, detached: boolean) {
code: proc.exitCode,
},
"proxy",
21,
ExitCodes.ProxyError,
);
return;
}
Expand Down
6 changes: 6 additions & 0 deletions src/util/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,12 @@ export async function getDirSize(dir: string): Promise<number> {
return size;
}

export async function isDiskFull(collDir: string) {
const diskUsage: Record<string, string> = await getDiskUsage(collDir);
const usedPercentage = parseInt(diskUsage["Use%"].slice(0, -1));
return usedPercentage >= 99;
}

export async function checkDiskUtilization(
collDir: string,
// TODO: Fix this the next time the file is edited.
Expand Down

0 comments on commit 5c9d808

Please sign in to comment.