Skip to content

Commit

Permalink
Improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Jun 5, 2022
1 parent dc3e531 commit 97848f4
Show file tree
Hide file tree
Showing 23 changed files with 66 additions and 99 deletions.
2 changes: 1 addition & 1 deletion src/combination/ids/name.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getCombDimensionsIds } from './get.js'
// Retrieve error message prefix showing a combination's dimension ids
export const getCombinationPrefix = function (combination, noDimensions) {
const combinationName = getCombinationName(combination, noDimensions)
return combinationName === '' ? '' : `In ${combinationName}:\n`
return combinationName === '' ? undefined : `In ${combinationName}.`
}

// Retrieve string with each combination's dimension id.
Expand Down
5 changes: 2 additions & 3 deletions src/combination/tasks/find.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { PluginError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'
import { measureCombinations } from '../../run/measure/main.js'

// Each combination has its own process, in order to prevent them from
Expand Down Expand Up @@ -27,8 +26,8 @@ export const findTasks = async function ({
)
validateDuplicateTaskIds(ids)
return ids.map((id) => ({ id, taskPath, runner }))
} catch (error) {
throw wrapError(error, `In tasks file "${taskPath}":\n`)
} catch (cause) {
throw new Error(`Tasks file: "${taskPath}"`, { cause })
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/combination/tasks/load.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { PluginError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'
import { computeRunnerVersions } from '../../top/system/versions/compute.js'

// Select the runners and retrieve their related spawn options using
Expand Down Expand Up @@ -30,7 +29,7 @@ export const loadRunner = async function (
const launchRunner = async function ({ id, config, launch }) {
try {
return await launch(config)
} catch (error) {
throw wrapError(error, `In runner '${id}':`, PluginError)
} catch (cause) {
throw new PluginError(`Could not launch runner "${id}"`, { cause })
}
}
5 changes: 2 additions & 3 deletions src/config/load/contents.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { inspect } from 'util'
import isPlainObj from 'is-plain-obj'

import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'
import { importJsDefault } from '../../utils/import.js'
import { loadYamlFile } from '../../utils/yaml.js'

Expand Down Expand Up @@ -32,8 +31,8 @@ export const loadConfigContents = async function (configPath) {
const loadContents = async function (loadFunc, configPath) {
try {
return await loadFunc(configPath)
} catch (error) {
throw wrapError(error, 'File cannot be loaded:', UserError)
} catch (cause) {
throw new UserError('File cannot be loaded.', { cause })
}
}

Expand Down
11 changes: 4 additions & 7 deletions src/config/load/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { dirname } from 'path'

import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'
import { addBases } from '../cwd.js'
import { deepMerge } from '../merge.js'

Expand Down Expand Up @@ -120,12 +119,10 @@ const getParentConfigWithBases = async function (configPath, childConfigPaths) {
childConfigPathsA,
)
return configWithBases
} catch (error) {
throw wrapError(
error,
`Invalid configuration file '${configPath}':\n`,
UserError,
)
} catch (cause) {
throw new UserError(`Invalid configuration file '${configPath}'.`, {
cause,
})
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/config/load/resolve.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { createRequire } from 'module'

import { wrapError } from '../../error/wrap.js'

// The `config` can be:
// - a Node module name starting with "[@scope/]spyd-config-"
// - a file path
Expand All @@ -19,10 +17,10 @@ const resolveNpm = function (configOpt, cwd) {
try {
return createRequire(`${cwd}/`).resolve(configOpt)
} catch (error) {
throw wrapError(
error,
throw new Error(
`must be a valid package name.
This Node module was not found, please ensure it is installed.\n`,
This Node module was not found, please ensure it is installed:\n`,
{ cause: error },
)
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/config/normalize/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'

import { normalizeInputs } from './lib/main.js'

Expand All @@ -13,7 +12,7 @@ export const normalizeConfig = async function (config, rules, opts) {
})

if (error) {
throw wrapError(error, '', UserError)
throw new UserError('', { cause: error })
}

return inputs
Expand Down
3 changes: 1 addition & 2 deletions src/config/plugin/error.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { CoreError, PluginError, UserError } from '../../error/main.js'
import { normalizeError } from '../../error/normalize/main.js'
import { wrapError } from '../../error/wrap.js'

// Translate error classes from the plugins library to error classes from this
// library
export const handlePluginsError = function (error) {
const { name } = normalizeError(error)
const ErrorType = name in ERROR_MAP ? ERROR_MAP[name] : CoreError
return wrapError(error, '', ErrorType)
return new ErrorType('', { cause: error })
}

const ERROR_MAP = {
Expand Down
23 changes: 10 additions & 13 deletions src/history/data/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { pathExists } from 'path-exists'
import { isDirectory, isFile } from 'path-type'

import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'

// Find all filenames of the history directory
export const listFilenames = async function (historyDir) {
Expand All @@ -15,26 +14,26 @@ export const listFilenames = async function (historyDir) {
export const readRawResult = async function (path) {
try {
return await readFile(path, 'utf8')
} catch (error) {
throw wrapError(error, 'History file could not be read:', UserError)
} catch (cause) {
throw new UserError('History file could not be read.', { cause })
}
}

// Write a rawResult's contents
export const writeRawResult = async function (path, rawResultStr) {
try {
return await writeFile(path, rawResultStr)
} catch (error) {
throw wrapError(error, 'History file could not be written:', UserError)
} catch (cause) {
throw new UserError('History file could not be written.', { cause })
}
}

// Delete a rawResult from the filesystem
export const deleteRawResult = async function (path) {
try {
await unlink(path)
} catch (error) {
throw wrapError(error, 'History file could not be deleted:', UserError)
} catch (cause) {
throw new UserError('History file could not be deleted.', { cause })
}
}

Expand All @@ -51,12 +50,10 @@ export const ensureHistoryDir = async function (historyDir) {

try {
await mkdir(historyDir, { recursive: true })
} catch (error) {
throw wrapError(
error,
`Could not create history directory "${historyDir}"\n`,
UserError,
)
} catch (cause) {
throw new UserError(`Could not create history directory "${historyDir}"`, {
cause,
})
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/history/delta/find.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'

import { getDeltaError } from './error.js'
import { findFormat } from './formats/main.js'
Expand Down Expand Up @@ -107,7 +106,7 @@ const findByDelta = async function ({ metadataGroups, delta, cwd, name }) {

try {
return await format.find(metadataGroups, delta.value, cwd)
} catch (error) {
throw wrapError(error, getDeltaError(delta, name))
} catch (cause) {
throw new UserError(`${getDeltaError(delta, name)}:`, { cause })
}
}
5 changes: 2 additions & 3 deletions src/history/delta/transform.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { wrapError } from '../../error/wrap.js'
import { findValue } from '../../utils/find.js'

import { getDeltaTypeMessage } from './error.js'
Expand Down Expand Up @@ -30,8 +29,8 @@ const parseDelta = function ({ parse, type }, deltaOriginal) {
try {
const value = parse(deltaOriginal)
return value === undefined ? undefined : { type, value }
} catch (error) {
throw wrapError(error, `\nType: ${getDeltaTypeMessage(type)}`)
} catch (cause) {
throw new Error(`must be a valid ${getDeltaTypeMessage(type)}.`, { cause })
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/history/serialize/contents.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'

// Parse the contents of a rawResult.
// Parsing/serializing rawResults is abstracted away from the main store logic,
// so that stores only need to deal with metadata objects and blob strings.
export const parseRawResult = function (rawResultStr) {
try {
return JSON.parse(rawResultStr)
} catch (error) {
throw wrapError(error, 'History files is invalid JSON:', UserError)
} catch (cause) {
throw new UserError('History file is invalid JSON.', { cause })
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/report/contents/get.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import omit from 'omit.js'

import { PluginError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'
import { FORMATS } from '../formats/list.js'

// Retrieve reporter's contents by calling all `reporter.report()` then
Expand Down Expand Up @@ -40,8 +39,8 @@ const callReportFunc = async function ({
startData,
])
return { content, result, format, footerString, output, colors }
} catch (error) {
throw wrapError(error, `When calling reporter "${id}":`, PluginError)
} catch (cause) {
throw new PluginError(`Could not call reporter "${id}".`, { cause })
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/report/contents/insert.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import stripFinalNewline from 'strip-final-newline'
import writeFileAtomic from 'write-file-atomic'

import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'

// By default, the `output` configuration property overwrites the file.
// However, contents can be inserted instead between any two lines with the
Expand Down Expand Up @@ -34,8 +33,8 @@ export const detectInsert = async function (output) {
const getFileContent = async function (output) {
try {
return await readFile(output, 'utf8')
} catch (error) {
throw wrapError(error, `Could not read "output" "${output}"\n`, UserError)
} catch (cause) {
throw new UserError(`Could not read "output" "${output}"`, { cause })
}
}

Expand Down Expand Up @@ -89,7 +88,7 @@ const END_LINE_TOKEN = 'spyd-end'
const writeFileContent = async function (output, fileContent) {
try {
await writeFileAtomic(output, fileContent)
} catch {
throw wrapError(`Could not write to file "${output}"\n`, UserError)
} catch (cause) {
throw new UserError(`Could not write to file "${output}"`, { cause })
}
}
9 changes: 2 additions & 7 deletions src/report/contents/output.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { dirname } from 'path'
import writeFileAtomic from 'write-file-atomic'

import { UserError } from '../../error/main.js'
import { wrapError } from '../../error/wrap.js'
import { printToStdout } from '../tty.js'

import { detectInsert, insertContents } from './insert.js'
Expand Down Expand Up @@ -47,11 +46,7 @@ const overwriteContents = async function (output, content) {

try {
await writeFileAtomic(output, content)
} catch (error) {
throw wrapError(
error,
`Could not write to "output" "${output}"\n`,
UserError,
)
} catch (cause) {
throw new UserError(`Could not write to "output" "${output}"`, { cause })
}
}
15 changes: 6 additions & 9 deletions src/report/start_end.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { PluginError } from '../error/main.js'
import { wrapError } from '../error/wrap.js'

// Call all `reporter.start()`
export const startReporters = async function (config) {
Expand All @@ -15,12 +14,10 @@ const startReporter = async function (reporter) {
try {
const startData = await reporter.start()
return { ...reporter, startData }
} catch (error) {
throw wrapError(
error,
`When starting reporter "${reporter.id}":`,
PluginError,
)
} catch (cause) {
throw new PluginError(`Could not start reporter "${reporter.id}".`, {
cause,
})
}
}

Expand All @@ -36,7 +33,7 @@ const endReporter = async function ({ end, startData, id }) {

try {
await end(startData)
} catch (error) {
throw wrapError(error, `When ending reporter "${id}":`, PluginError)
} catch (cause) {
throw new PluginError(`Could not end reporter "${id}".`, { cause })
}
}
2 changes: 1 addition & 1 deletion src/run/logs/additional.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const getAdditionalMessage = function (taskLogs) {
return ''
}

return `${additionalMessage.message}\n`
return `${additionalMessage.message}\n\n`
}

const ADDITIONAL_MESSAGES = [
Expand Down
6 changes: 3 additions & 3 deletions src/run/logs/error.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Buffer } from 'buffer'
import { open } from 'fs/promises'

import { wrapError } from '../../error/wrap.js'

import { getAdditionalMessage } from './additional.js'
import { normalizeLogs } from './normalize.js'

Expand All @@ -21,7 +19,9 @@ export const addErrorTaskLogs = async function (error, logsPath) {
}

const additionalMessage = getAdditionalMessage(taskLogsA)
return wrapError(error, `\n${additionalMessage}\nTask logs:\n${taskLogsA}`)
return new Error(`${additionalMessage}Task logs:\n${taskLogsA}`, {
cause: error,
})
}

// Read the last lines from the logs file
Expand Down
Loading

0 comments on commit 97848f4

Please sign in to comment.