Skip to content

Commit

Permalink
feat(detectors): Add timeout on executing detectors
Browse files Browse the repository at this point in the history
Closes #47
  • Loading branch information
jubnzv committed Oct 24, 2024
1 parent 9eebff4 commit 16914d8
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Import Graph: PR [#180](https://github.com/nowarp/misti/pull/180)
- Leverage `ImportGraph` to resolve entry points: PR [#194](https://github.com/nowarp/misti/pull/194)
- Accept directory as input: PR [#195](https://github.com/nowarp/misti/pull/195)
- Timeout on executing detectors: Issue [#47](https://github.com/nowarp/misti/issues/47)

### Changed
- Improved and optimized the test suite: PR [#184](https://github.com/nowarp/misti/pull/184)
Expand Down
24 changes: 20 additions & 4 deletions src/cli/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CLIOptions, cliOptionDefaults } from "./options";
import { MistiResult, ToolOutput, WarningOutput } from "./result";
import { OutputFormat } from "./types";
import { Detector, findBuiltInDetector } from "../detectors/detector";
import { MistiEnv } from "../internals/config";
import { MistiContext } from "../internals/context";
import { ExecutionException, InternalException } from "../internals/exceptions";
import { CompilationUnit, ImportGraph, ProjectName } from "../internals/ir";
Expand All @@ -20,6 +21,7 @@ import fs from "fs";
import ignore from "ignore";
import JSONbig from "json-bigint";
import path from "path";
import { setTimeout } from "timers/promises";

/**
* Manages the initialization and execution of detectors for analyzing compilation units.
Expand Down Expand Up @@ -348,7 +350,7 @@ export class Driver {
const result = [] as string[];
if (err instanceof Error) {
result.push(err.message);
if (err.stack !== undefined && process.env.MISTI_TRACE === "1") {
if (err.stack !== undefined && MistiEnv.MISTI_TRACE) {
result.push(err.stack);
}
} else {
Expand Down Expand Up @@ -591,9 +593,23 @@ export class Driver {
return [];
}
this.ctx.logger.debug(`${cu.projectName}: Running ${detector.id}`);
const warnings = await detector.check(cu);
this.ctx.logger.debug(`${cu.projectName}: Finished ${detector.id}`);
return warnings;
try {
const warnings = await Promise.race([
detector.check(cu),
setTimeout(MistiEnv.MISTI_TIMEOUT, []).then(() => {
throw new Error(
`Detector ${detector.id} timed out after ${MistiEnv.MISTI_TIMEOUT}ms`,
);
}),
]);
this.ctx.logger.debug(`${cu.projectName}: Finished ${detector.id}`);
return warnings;
} catch (error) {
this.ctx.logger.error(
`${cu.projectName}: Error in ${detector.id}: ${error}`,
);
return [];
}
});
try {
return (await Promise.all(warningsPromises)).flat();
Expand Down
20 changes: 20 additions & 0 deletions src/internals/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,23 @@ export class MistiConfig {
});
}
}

/**
* Environment variables to configure advanced Misti options.
*/
export class MistiEnv {
/**
* Timeout for the detector execution in milliseconds.
*/
public static MISTI_TIMEOUT: number = parseInt(
process.env.MISTI_TIMEOUT || "15000",
10,
);

/**
* Whether to trace the execution.
*/
public static MISTI_TRACE: boolean = process.env.MISTI_TRACE
? process.env.MISTI_TRACE === "1"
: false;
}
4 changes: 2 additions & 2 deletions src/internals/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MistiConfig } from "./config";
import { MistiConfig, MistiEnv } from "./config";
import { DebugLogger, Logger, QuietLogger, TraceLogger } from "./logger";
import { CLIOptions, cliOptionDefaults } from "../cli";
import { throwZodError } from "./exceptions";
Expand Down Expand Up @@ -56,7 +56,7 @@ export class MistiContext {
: new Logger();

// Add backtraces to the logger output if requested
if (process.env.MISTI_TRACE === "1") {
if (MistiEnv.MISTI_TRACE) {
this.logger = new TraceLogger();
}
}
Expand Down

0 comments on commit 16914d8

Please sign in to comment.