Skip to content

Commit

Permalink
fix: extra error handling and debugging [IAC-3138]
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiu-snyk committed Nov 14, 2024
1 parent 8956366 commit 7fbae0f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
20 changes: 20 additions & 0 deletions src/cli/commands/test/iac/scan.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as cloneDeep from 'lodash.clonedeep';
import * as assign from 'lodash.assign';
import * as debugLib from 'debug';

import {
IacFileInDirectory,
Expand Down Expand Up @@ -30,6 +31,8 @@ import { getRepositoryRootForPath } from '../../../../lib/iac/git';
import { getInfo } from '../../../../lib/project-metadata/target-builders/git';
import { buildMeta, GitRepository, GitRepositoryFinder } from './meta';

const debug = debugLib('snyk-iac');

export async function scan(
iacOrgSettings: IacOrgSettings,
options: any,
Expand Down Expand Up @@ -109,6 +112,7 @@ export async function scan(
iacScanFailures = [...iacScanFailures, ...(failures || [])];
iacIgnoredIssuesCount += ignoreCount;
} catch (error) {
debug(`Scan error for path ${path}, details below`);
res = formatTestError(error);
}

Expand Down Expand Up @@ -155,12 +159,17 @@ export async function scan(
function formatTestError(error) {
let errorResponse;
if (error instanceof Error) {
debug(`Error: ${error.name} ${error.message}`);
debug(`Stack trace: ${error.stack}`);
errorResponse = error;
} else if (Array.isArray(error)) {
return error.map(formatTestError);
} else if (typeof error !== 'object') {
debug(`Error value: ${error}`);
errorResponse = new Error(error);
} else {
// we should not get here, but if we do, we want to log the thrown object
debug('Unexpected error object:', safeStringify(error));
try {
errorResponse = JSON.parse(error.message);
} catch (unused) {
Expand All @@ -170,6 +179,17 @@ function formatTestError(error) {
return errorResponse;
}

function safeStringify(obj: unknown): string {
try {
return JSON.stringify(obj);
} catch (e) {
if (e instanceof Error) {
return `Error stringifying object: ${e.message}`;
}
return `Error stringifying object`;
}
}

class CurrentWorkingDirectoryTraversalError extends CustomError {
public filename: string;
public projectRoot: string;
Expand Down
23 changes: 20 additions & 3 deletions src/lib/snyk-test/iac-test-result.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import pick = require('lodash.pick');
import { CustomError } from '../errors';
import { BasicResultData, SEVERITY, TestDepGraphMeta } from './legacy';
import * as debugLib from 'debug';

const debug = debugLib('snyk-iac');

export interface AnnotatedIacIssue {
id: string;
Expand Down Expand Up @@ -58,10 +61,24 @@ const IAC_ISSUES_KEY = 'infrastructureAsCodeIssues';
export function mapIacTestResult(
iacTest: IacTestResponse,
): MappedIacTestResponse | IacTestError {
if (iacTest instanceof CustomError) {
if (iacTest instanceof Error) {
return mapIacTestError(iacTest);
}

if (!iacTest.result) {
// This is an unexpected scenario, we should always have a result object,
// but if we don't, we should handle it gracefully.
debug(`invalid scan result: ${iacTest}`);
const errorMessage = iacTest.path
? `Invalid result for ${iacTest.path}`
: 'Invalid result';
return mapIacTestError(
new CustomError(
`${errorMessage}. Please run the command again with the \`-d\` flag and contact [email protected] with the contents of the output`,
),
);
}

const infrastructureAsCodeIssues =
iacTest?.result?.cloudConfigResults.map(mapIacIssue) || [];
const {
Expand All @@ -76,10 +93,10 @@ export function mapIacTestResult(
};
}

export function mapIacTestError(error: CustomError) {
export function mapIacTestError(error: Error) {
return {
ok: false,
code: error.code,
code: error instanceof CustomError ? error.code : undefined,
error: error.message,
path: (error as any).path,
};
Expand Down

0 comments on commit 7fbae0f

Please sign in to comment.