From c1d8b6baa02522b02cc9105483194c8174a6354f Mon Sep 17 00:00:00 2001 From: Edward Ezekiel Date: Wed, 30 Apr 2025 10:38:20 -0500 Subject: [PATCH 1/4] chore: switch to throw error instead of this.error --- src/api/client.ts | 5 ++--- src/api/nes/nes.client.ts | 2 +- src/commands/report/committers.ts | 18 +++++++++--------- src/commands/report/purls.ts | 17 +++++++---------- src/commands/scan/eol.ts | 18 ++++++++---------- src/commands/scan/sbom.ts | 18 ++++++++---------- src/service/error.svc.ts | 25 ------------------------- src/service/nes/nes.svc.ts | 8 +++++++- 8 files changed, 42 insertions(+), 69 deletions(-) diff --git a/src/api/client.ts b/src/api/client.ts index 73aca2dc..a55fc443 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -1,5 +1,4 @@ import * as apollo from '@apollo/client/core/index.js'; -import { ApolloError } from '../service/error.svc.ts'; export interface ApolloHelper { mutate( @@ -41,7 +40,7 @@ export class ApolloClient implements ApolloHelper { variables, }); } catch (error: unknown) { - throw new ApolloError('GraphQL mutation failed', error); + throw new Error('GraphQL mutation failed', { cause: error }); } } @@ -52,7 +51,7 @@ export class ApolloClient implements ApolloHelper { variables, }); } catch (error) { - throw new ApolloError('GraphQL query failed', error); + throw new Error('GraphQL query failed', { cause: error }); } } } diff --git a/src/api/nes/nes.client.ts b/src/api/nes/nes.client.ts index b65a543c..ccb4e1b1 100644 --- a/src/api/nes/nes.client.ts +++ b/src/api/nes/nes.client.ts @@ -75,7 +75,7 @@ export const batchSubmitPurls = async ( return handleBatchResults(results); } catch (error) { debugLogger('Fatal error in batchSubmitPurls: %s', error); - throw new Error(`Failed to process purls: ${error instanceof Error ? error.message : String(error)}`); + throw new Error('Failed to process purls', { cause: error }); } }; diff --git a/src/commands/report/committers.ts b/src/commands/report/committers.ts index 616c5688..bd8a4818 100644 --- a/src/commands/report/committers.ts +++ b/src/commands/report/committers.ts @@ -12,7 +12,7 @@ import { groupCommitsByMonth, parseGitLogOutput, } from '../../service/committers.svc.ts'; -import { getErrorMessage, isErrnoException } from '../../service/error.svc.ts'; +import { isErrnoException } from '../../service/error.svc.ts'; export default class Committers extends Command { static override description = 'Generate report of committers to a git repository'; @@ -64,7 +64,7 @@ export default class Committers extends Command { fs.writeFileSync(path.resolve('eol.committers.json'), JSON.stringify(reportData, null, 2)); this.log('Report written to json'); } catch (error) { - this.error(`Failed to save JSON report: ${getErrorMessage(error)}`); + throw new Error('Failed to save JSON report', { cause: error }); } } return reportData; @@ -80,7 +80,7 @@ export default class Committers extends Command { fs.writeFileSync(path.resolve('eol.committers.csv'), csvOutput); this.log('Report written to csv'); } catch (error) { - this.error(`Failed to save CSV report: ${getErrorMessage(error)}`); + throw new Error('Failed to save CSV report', { cause: error }); } } else { this.log(textOutput); @@ -93,14 +93,14 @@ export default class Committers extends Command { fs.writeFileSync(path.resolve('eol.committers.txt'), textOutput); this.log('Report written to txt'); } catch (error) { - this.error(`Failed to save txt report: ${getErrorMessage(error)}`); + throw new Error('Failed to save txt report', { cause: error }); } } else { this.log(textOutput); } return textOutput; } catch (error) { - this.error(`Failed to generate report: ${getErrorMessage(error)}`); + throw new Error('Failed to generate report', { cause: error }); } } @@ -152,15 +152,15 @@ export default class Committers extends Command { if (logProcess.error) { if (isErrnoException(logProcess.error)) { if (logProcess.error.code === 'ENOENT') { - this.error('Git command not found. Please ensure git is installed and available in your PATH.'); + throw new Error('Git command not found. Please ensure git is installed and available in your PATH.'); } - this.error(`Git command failed: ${getErrorMessage(logProcess.error)}`); + throw new Error('Git command failed', { cause: logProcess.error }); } - this.error(`Git command failed: ${getErrorMessage(logProcess.error)}`); + throw new Error('Git command failed', { cause: logProcess.error }); } if (logProcess.status !== 0) { - this.error(`Git command failed with status ${logProcess.status}: ${logProcess.stderr}`); + throw new Error(`Git command failed with status ${logProcess.status}`, { cause: logProcess.stderr }); } if (!logProcess.stdout) { diff --git a/src/commands/report/purls.ts b/src/commands/report/purls.ts index 591dfcda..a0f58dc9 100644 --- a/src/commands/report/purls.ts +++ b/src/commands/report/purls.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { Command, Flags, ux } from '@oclif/core'; -import { getErrorMessage, isErrnoException } from '../../service/error.svc.ts'; +import { isErrnoException } from '../../service/error.svc.ts'; import { extractPurls, getPurlOutput } from '../../service/purls.svc.ts'; import ScanSbom from '../scan/sbom.ts'; @@ -66,26 +66,23 @@ export default class ReportPurls extends Command { if (isErrnoException(error)) { switch (error.code) { case 'EACCES': - this.error('Permission denied: Cannot write to output file'); - break; + throw new Error('Permission denied: Cannot write to output file'); case 'ENOSPC': - this.error('No space left on device'); - break; + throw new Error('No space left on device'); case 'EISDIR': - this.error('Cannot write to output file: Is a directory'); - break; + throw new Error('Cannot write to output file: Is a directory'); default: - this.error(`Failed to save purls: ${getErrorMessage(error)}`); + throw new Error('Failed to save purls', { cause: error }); } } - this.error(`Failed to save purls: ${getErrorMessage(error)}`); + throw new Error('Failed to save purls', { cause: error }); } } // Return wrapped object with metadata return { purls }; } catch (error) { - this.error(`Failed to generate PURLs: ${getErrorMessage(error)}`); + throw new Error('Failed to generate PURLs', { cause: error }); } } } diff --git a/src/commands/scan/eol.ts b/src/commands/scan/eol.ts index 607f945e..dca134d7 100644 --- a/src/commands/scan/eol.ts +++ b/src/commands/scan/eol.ts @@ -5,7 +5,7 @@ import { batchSubmitPurls } from '../../api/nes/nes.client.ts'; import type { ScanResult } from '../../api/types/hd-cli.types.js'; import type { ComponentStatus, InsightsEolScanComponent } from '../../api/types/nes.types.ts'; import type { Sbom } from '../../service/eol/cdx.svc.ts'; -import { getErrorMessage, isErrnoException } from '../../service/error.svc.ts'; +import { isErrnoException } from '../../service/error.svc.ts'; import { extractPurls, parsePurlsFile } from '../../service/purls.svc.ts'; import { createStatusDisplay, createTableForStatus, groupComponentsByStatus } from '../../ui/eol.ui.ts'; import { INDICATORS, STATUS_COLORS } from '../../ui/shared.ui.ts'; @@ -91,7 +91,7 @@ export default class ScanEol extends Command { const purlsFileString = fs.readFileSync(filePath, 'utf8'); return parsePurlsFile(purlsFileString); } catch (error) { - this.error(`Failed to read purls file. ${getErrorMessage(error)}`); + throw new Error('Failed to read purls file', { cause: error }); } } @@ -102,12 +102,12 @@ export default class ScanEol extends Command { try { purls = await extractPurls(sbom); } catch (error) { - this.error(`Failed to extract purls from sbom. ${getErrorMessage(error)}`); + throw new Error('Failed to extract purls from sbom', { cause: error }); } try { scan = await batchSubmitPurls(purls); } catch (error) { - this.error(`Failed to submit scan to NES from sbom. ${getErrorMessage(error)}`); + throw new Error('Failed to submit scan to NES from sbom', { cause: error }); } if (scan.components.size === 0) { @@ -132,17 +132,15 @@ export default class ScanEol extends Command { this.log('Report saved to eol.report.json'); } catch (error) { if (!isErrnoException(error)) { - this.error(`Failed to save report: ${getErrorMessage(error)}`); + throw new Error('Failed to save report', { cause: error }); } switch (error.code) { case 'EACCES': - this.error('Permission denied. Unable to save report to eol.report.json'); - break; + throw new Error('Permission denied. Unable to save report to eol.report.json'); case 'ENOSPC': - this.error('No space left on device. Unable to save report to eol.report.json'); - break; + throw new Error('No space left on device. Unable to save report to eol.report.json'); default: - this.error(`Failed to save report: ${getErrorMessage(error)}`); + throw new Error('Failed to save report', { cause: error }); } } } diff --git a/src/commands/scan/sbom.ts b/src/commands/scan/sbom.ts index c6a45d69..e4bd4fca 100644 --- a/src/commands/scan/sbom.ts +++ b/src/commands/scan/sbom.ts @@ -4,7 +4,6 @@ import { join, resolve } from 'node:path'; import { Command, Flags, ux } from '@oclif/core'; import type { Sbom } from '../../service/eol/cdx.svc.ts'; import { createSbom, validateIsCycloneDxSbom } from '../../service/eol/eol.svc.ts'; -import { getErrorMessage } from '../../service/error.svc.ts'; export default class ScanSbom extends Command { static override description = 'Scan a SBOM for purls'; @@ -69,7 +68,7 @@ export default class ScanSbom extends Command { // Validate that exactly one of --file or --dir is provided if (file && dir) { - this.error('Cannot specify both --file and --dir flags. Please use one or the other.'); + throw new Error('Cannot specify both --file and --dir flags. Please use one or the other.'); } let sbom: Sbom; const path = dir || process.cwd(); @@ -93,11 +92,10 @@ export default class ScanSbom extends Command { const dir = resolve(_dirFlag); try { if (!fs.existsSync(dir)) { - this.error(`Directory not found: ${dir}`); + throw new Error(`Directory not found: ${dir}`); } const stats = fs.statSync(dir); if (!stats.isDirectory()) { - this.error(`Path is not a directory: ${dir}`); } ux.action.start(`Scanning ${dir}`); @@ -105,11 +103,11 @@ export default class ScanSbom extends Command { const options = this.getScanOptions(); const sbom = await createSbom(dir, options); if (!sbom) { - this.error(`SBOM failed to generate for dir: ${dir}`); + throw new Error(`SBOM failed to generate: ${dir}`); } return sbom; } catch (error) { - this.error(`Failed to scan directory: ${getErrorMessage(error)}`); + throw new Error('Failed to scan directory', { cause: error }); } } @@ -131,7 +129,7 @@ export default class ScanSbom extends Command { workerProcess.unref(); } catch (error) { - this.error(`Failed to start background scan: ${getErrorMessage(error)}`); + throw new Error('Failed to start background scan', { cause: error }); } } @@ -139,7 +137,7 @@ export default class ScanSbom extends Command { const file = resolve(_fileFlag); try { if (!fs.existsSync(file)) { - this.error(`SBOM file not found: ${file}`); + throw new Error(`SBOM file not found: ${file}`); } ux.action.start(`Loading sbom from ${file}`); @@ -152,7 +150,7 @@ export default class ScanSbom extends Command { validateIsCycloneDxSbom(sbom); return sbom; } catch (error) { - this.error(`Failed to read SBOM file: ${getErrorMessage(error)}`); + throw new Error('Failed to read SBOM file', { cause: error }); } } @@ -164,7 +162,7 @@ export default class ScanSbom extends Command { this.log(`SBOM saved to ${outputPath}`); } } catch (error) { - this.error(`Failed to save SBOM: ${getErrorMessage(error)}`); + throw new Error('Failed to save SBOM', { cause: error }); } } } diff --git a/src/service/error.svc.ts b/src/service/error.svc.ts index 9a0df49e..1053d65d 100644 --- a/src/service/error.svc.ts +++ b/src/service/error.svc.ts @@ -5,28 +5,3 @@ export const isError = (error: unknown): error is Error => { export const isErrnoException = (error: unknown): error is NodeJS.ErrnoException => { return isError(error) && 'code' in error; }; - -export const isApolloError = (error: unknown): error is ApolloError => { - return error instanceof ApolloError; -}; - -export const getErrorMessage = (error: unknown): string => { - if (isError(error)) { - return error.message; - } - return 'Unknown error'; -}; - -export class ApolloError extends Error { - public readonly originalError?: unknown; - - constructor(message: string, original?: unknown) { - if (isError(original)) { - super(`${message}: ${original.message}`); - } else { - super(`${message}: ${String(original)}`); - } - this.name = 'ApolloError'; - this.originalError = original; - } -} diff --git a/src/service/nes/nes.svc.ts b/src/service/nes/nes.svc.ts index be4c11f8..19d5e989 100644 --- a/src/service/nes/nes.svc.ts +++ b/src/service/nes/nes.svc.ts @@ -27,7 +27,13 @@ export const SbomScanner = (client: NesApolloClient) => async (purls: string[], options: ScanInputOptions): Promise => { const { type, page, totalPages, scanId } = options; - const input: InsightsEolScanInput = { components: purls, type, page, totalPages, scanId }; + const input: InsightsEolScanInput = { + components: purls, + type, + page, + totalPages, + scanId, + }; const res = await client.mutate(M_SCAN.gql, { input }); From eef49101cbdfac7afccddfb3060e12af414a0fb3 Mon Sep 17 00:00:00 2001 From: Edward Ezekiel Date: Wed, 30 Apr 2025 10:57:58 -0500 Subject: [PATCH 2/4] chore: refactor catches to match node docs --- src/api/client.ts | 8 ++++---- src/api/nes/nes.client.ts | 6 +++--- src/commands/report/committers.ts | 16 ++++++++-------- src/commands/report/purls.ts | 14 +++++++------- src/commands/scan/eol.ts | 24 ++++++++++++------------ src/commands/scan/sbom.ts | 16 ++++++++-------- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/api/client.ts b/src/api/client.ts index a55fc443..16fe8255 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -39,8 +39,8 @@ export class ApolloClient implements ApolloHelper { mutation, variables, }); - } catch (error: unknown) { - throw new Error('GraphQL mutation failed', { cause: error }); + } catch (cause: unknown) { + throw new Error('GraphQL mutation failed', { cause }); } } @@ -50,8 +50,8 @@ export class ApolloClient implements ApolloHelper { query, variables, }); - } catch (error) { - throw new Error('GraphQL query failed', { cause: error }); + } catch (cause: unknown) { + throw new Error('GraphQL query failed', { cause }); } } } diff --git a/src/api/nes/nes.client.ts b/src/api/nes/nes.client.ts index ccb4e1b1..621720d6 100644 --- a/src/api/nes/nes.client.ts +++ b/src/api/nes/nes.client.ts @@ -73,9 +73,9 @@ export const batchSubmitPurls = async ( const results = await processBatches(batches, options); return handleBatchResults(results); - } catch (error) { - debugLogger('Fatal error in batchSubmitPurls: %s', error); - throw new Error('Failed to process purls', { cause: error }); + } catch (cause: unknown) { + debugLogger('Fatal error in batchSubmitPurls: %s', cause); + throw new Error('Failed to process purls', { cause }); } }; diff --git a/src/commands/report/committers.ts b/src/commands/report/committers.ts index bd8a4818..3867fa28 100644 --- a/src/commands/report/committers.ts +++ b/src/commands/report/committers.ts @@ -63,8 +63,8 @@ export default class Committers extends Command { try { fs.writeFileSync(path.resolve('eol.committers.json'), JSON.stringify(reportData, null, 2)); this.log('Report written to json'); - } catch (error) { - throw new Error('Failed to save JSON report', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to save JSON report', { cause }); } } return reportData; @@ -79,8 +79,8 @@ export default class Committers extends Command { try { fs.writeFileSync(path.resolve('eol.committers.csv'), csvOutput); this.log('Report written to csv'); - } catch (error) { - throw new Error('Failed to save CSV report', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to save CSV report', { cause }); } } else { this.log(textOutput); @@ -92,15 +92,15 @@ export default class Committers extends Command { try { fs.writeFileSync(path.resolve('eol.committers.txt'), textOutput); this.log('Report written to txt'); - } catch (error) { - throw new Error('Failed to save txt report', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to save txt report', { cause }); } } else { this.log(textOutput); } return textOutput; - } catch (error) { - throw new Error('Failed to generate report', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to generate report', { cause }); } } diff --git a/src/commands/report/purls.ts b/src/commands/report/purls.ts index a0f58dc9..1c2fff7e 100644 --- a/src/commands/report/purls.ts +++ b/src/commands/report/purls.ts @@ -62,9 +62,9 @@ export default class ReportPurls extends Command { fs.writeFileSync(outputPath, purlOutput); this.log('Purls saved to %s', outputPath); - } catch (error: unknown) { - if (isErrnoException(error)) { - switch (error.code) { + } catch (cause: unknown) { + if (isErrnoException(cause)) { + switch (cause.code) { case 'EACCES': throw new Error('Permission denied: Cannot write to output file'); case 'ENOSPC': @@ -72,17 +72,17 @@ export default class ReportPurls extends Command { case 'EISDIR': throw new Error('Cannot write to output file: Is a directory'); default: - throw new Error('Failed to save purls', { cause: error }); + throw new Error('Failed to save purls', { cause }); } } - throw new Error('Failed to save purls', { cause: error }); + throw new Error('Failed to save purls', { cause }); } } // Return wrapped object with metadata return { purls }; - } catch (error) { - throw new Error('Failed to generate PURLs', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to generate PURLs', { cause }); } } } diff --git a/src/commands/scan/eol.ts b/src/commands/scan/eol.ts index dca134d7..6f66b6f0 100644 --- a/src/commands/scan/eol.ts +++ b/src/commands/scan/eol.ts @@ -90,8 +90,8 @@ export default class ScanEol extends Command { try { const purlsFileString = fs.readFileSync(filePath, 'utf8'); return parsePurlsFile(purlsFileString); - } catch (error) { - throw new Error('Failed to read purls file', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to read purls file', { cause }); } } @@ -100,14 +100,14 @@ export default class ScanEol extends Command { let purls: string[]; try { - purls = await extractPurls(sbom); - } catch (error) { - throw new Error('Failed to extract purls from sbom', { cause: error }); + purls = extractPurls(sbom); + } catch (cause: unknown) { + throw new Error('Failed to extract purls from sbom', { cause }); } try { scan = await batchSubmitPurls(purls); - } catch (error) { - throw new Error('Failed to submit scan to NES from sbom', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to submit scan to NES from sbom', { cause }); } if (scan.components.size === 0) { @@ -130,17 +130,17 @@ export default class ScanEol extends Command { try { fs.writeFileSync(reportPath, JSON.stringify({ components }, null, 2)); this.log('Report saved to eol.report.json'); - } catch (error) { - if (!isErrnoException(error)) { - throw new Error('Failed to save report', { cause: error }); + } catch (cause: unknown) { + if (!isErrnoException(cause)) { + throw new Error('Failed to save report', { cause }); } - switch (error.code) { + switch (cause.code) { case 'EACCES': throw new Error('Permission denied. Unable to save report to eol.report.json'); case 'ENOSPC': throw new Error('No space left on device. Unable to save report to eol.report.json'); default: - throw new Error('Failed to save report', { cause: error }); + throw new Error('Failed to save report', { cause }); } } } diff --git a/src/commands/scan/sbom.ts b/src/commands/scan/sbom.ts index e4bd4fca..2029c285 100644 --- a/src/commands/scan/sbom.ts +++ b/src/commands/scan/sbom.ts @@ -106,8 +106,8 @@ export default class ScanSbom extends Command { throw new Error(`SBOM failed to generate: ${dir}`); } return sbom; - } catch (error) { - throw new Error('Failed to scan directory', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to scan directory', { cause }); } } @@ -128,8 +128,8 @@ export default class ScanSbom extends Command { }); workerProcess.unref(); - } catch (error) { - throw new Error('Failed to start background scan', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to start background scan', { cause }); } } @@ -149,8 +149,8 @@ export default class ScanSbom extends Command { const sbom = JSON.parse(fileContent) as Sbom; validateIsCycloneDxSbom(sbom); return sbom; - } catch (error) { - throw new Error('Failed to read SBOM file', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to read SBOM file', { cause }); } } @@ -161,8 +161,8 @@ export default class ScanSbom extends Command { if (!this.jsonEnabled()) { this.log(`SBOM saved to ${outputPath}`); } - } catch (error) { - throw new Error('Failed to save SBOM', { cause: error }); + } catch (cause: unknown) { + throw new Error('Failed to save SBOM', { cause }); } } } From c2f525a5a669d3a6b5ee3c1c5775a6bdb5edb2e9 Mon Sep 17 00:00:00 2001 From: Edward Ezekiel Date: Wed, 30 Apr 2025 11:57:32 -0500 Subject: [PATCH 3/4] feat: throw error from main.js instead of exiting --- bin/main.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/main.js b/bin/main.js index 7a92fedf..eb739a70 100644 --- a/bin/main.js +++ b/bin/main.js @@ -22,7 +22,10 @@ async function main(isProduction = false) { dir: new URL('./dev.js', import.meta.url), }); } catch (error) { - process.exit(1); + if (error instanceof Error) { + throw error; + } + throw new Error(String(error)); } } From 6dceb63e6d128b02c9dce79650a412a1b84e4faa Mon Sep 17 00:00:00 2001 From: Edward Ezekiel Date: Wed, 30 Apr 2025 12:36:27 -0500 Subject: [PATCH 4/4] chore: ensure cause is thrown with error --- src/commands/report/committers.ts | 4 +++- src/commands/report/purls.ts | 6 +++--- src/commands/scan/eol.ts | 4 ++-- src/service/nes/nes.svc.ts | 2 +- src/ui/date.ui.ts | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/commands/report/committers.ts b/src/commands/report/committers.ts index 3867fa28..a6d24eab 100644 --- a/src/commands/report/committers.ts +++ b/src/commands/report/committers.ts @@ -152,7 +152,9 @@ export default class Committers extends Command { if (logProcess.error) { if (isErrnoException(logProcess.error)) { if (logProcess.error.code === 'ENOENT') { - throw new Error('Git command not found. Please ensure git is installed and available in your PATH.'); + throw new Error('Git command not found. Please ensure git is installed and available in your PATH.', { + cause: logProcess.error, + }); } throw new Error('Git command failed', { cause: logProcess.error }); } diff --git a/src/commands/report/purls.ts b/src/commands/report/purls.ts index 1c2fff7e..b0c1c53d 100644 --- a/src/commands/report/purls.ts +++ b/src/commands/report/purls.ts @@ -66,11 +66,11 @@ export default class ReportPurls extends Command { if (isErrnoException(cause)) { switch (cause.code) { case 'EACCES': - throw new Error('Permission denied: Cannot write to output file'); + throw new Error('Permission denied: Cannot write to output file', { cause }); case 'ENOSPC': - throw new Error('No space left on device'); + throw new Error('No space left on device', { cause }); case 'EISDIR': - throw new Error('Cannot write to output file: Is a directory'); + throw new Error('Cannot write to output file: Is a directory', { cause }); default: throw new Error('Failed to save purls', { cause }); } diff --git a/src/commands/scan/eol.ts b/src/commands/scan/eol.ts index 6f66b6f0..d46e125d 100644 --- a/src/commands/scan/eol.ts +++ b/src/commands/scan/eol.ts @@ -136,9 +136,9 @@ export default class ScanEol extends Command { } switch (cause.code) { case 'EACCES': - throw new Error('Permission denied. Unable to save report to eol.report.json'); + throw new Error('Permission denied. Unable to save report to eol.report.json', { cause }); case 'ENOSPC': - throw new Error('No space left on device. Unable to save report to eol.report.json'); + throw new Error('No space left on device. Unable to save report to eol.report.json', { cause }); default: throw new Error('Failed to save report', { cause }); } diff --git a/src/service/nes/nes.svc.ts b/src/service/nes/nes.svc.ts index 19d5e989..95b3963f 100644 --- a/src/service/nes/nes.svc.ts +++ b/src/service/nes/nes.svc.ts @@ -42,7 +42,7 @@ export const SbomScanner = debugLogger('failed scan %o', scan || {}); debugLogger('scan failed'); - throw new Error('Failed to provide scan: '); + throw new Error(`Scan failed: ${scan?.message}`); } return scan; diff --git a/src/ui/date.ui.ts b/src/ui/date.ui.ts index 5a92476a..fe515e02 100644 --- a/src/ui/date.ui.ts +++ b/src/ui/date.ui.ts @@ -8,7 +8,7 @@ export function parseMomentToSimpleDate(momentDate: string | Date | number | nul throw new Error('Invalid date'); } return dateObj.toISOString().split('T')[0]; - } catch { - throw new Error('Invalid date'); + } catch (cause: unknown) { + throw new Error('Invalid date', { cause }); } }