Skip to content

Commit

Permalink
Split file
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed Jun 5, 2022
1 parent 3db449b commit c0573b3
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 49 deletions.
53 changes: 53 additions & 0 deletions src/error/merge/aggregate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { setErrorProperty } from '../normalize/set.js'

// Keep `error.errors` when merging errors.
// If multiple errors have `errors`, the parent's errors are prepended.
// `error.errors[*].cause` are recursed.
// We do not merge `error.errors` into a single error:
// - Because:
// - Unlike `error.cause`, those are separate errors, which should remain so
// - Each error's message and stack trace should be kept as is, otherwise:
// - Those could be very long if `error.errors` is large
// - Those could lead to confusing stack traces
// - I.e. it is the responsibility of the consumers to recurse and handle
// `error.errors`
export const mergeAggregate = function ({
mergedError,
parentErrors,
child,
mergeErrorCause,
}) {
const childErrors = getAggregateErrors(child, mergeErrorCause)

if (parentErrors === undefined && childErrors === undefined) {
return
}

const errors = getMergedErrors(parentErrors, childErrors)
setErrorProperty(mergedError, 'errors', errors)
}

export const getAggregateErrors = function (error, mergeErrorCause) {
return Array.isArray(error.errors)
? error.errors.map(mergeErrorCause)
: undefined
}

const getMergedErrors = function (parentErrors, childErrors) {
if (parentErrors === undefined) {
return childErrors
}

if (childErrors === undefined) {
return parentErrors
}

return [...childErrors, ...parentErrors]
}

// Set `error.errors` when there are no `error.cause.errors`
export const setAggregate = function (parent, parentErrors) {
if (parentErrors !== undefined) {
setErrorProperty(parent, 'errors', parentErrors)
}
}
56 changes: 7 additions & 49 deletions src/error/merge/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { normalizeError } from '../normalize/main.js'
import { setErrorProperty } from '../normalize/set.js'

import {
setAggregate,
getAggregateErrors,
mergeAggregate,
} from './aggregate.js'
import { createError } from './create.js'
import { mergeMessage } from './message.js'
import { copyProps } from './props.js'
Expand Down Expand Up @@ -40,7 +44,7 @@ import { hasStack, fixStack } from './stack.js'
export const mergeErrorCause = function (error) {
const hasChildStack = hasStack(error.cause)
const parent = normalizeError(error)
const parentErrors = getAggregateErrors(parent)
const parentErrors = getAggregateErrors(parent, mergeErrorCause)

if (parent.cause === undefined) {
setAggregate(parent, parentErrors)
Expand All @@ -55,53 +59,7 @@ const mergeCause = function (parent, parentErrors, hasChildStack) {
const message = mergeMessage(parent.message, child.message)
const mergedError = createError(parent, child, message)
fixStack({ mergedError, parent, child, hasChildStack })
mergeAggregate(mergedError, parentErrors, child)
mergeAggregate({ mergedError, parentErrors, child, mergeErrorCause })
copyProps(mergedError, parent, child)
return normalizeError(mergedError)
}

// Keep `error.errors` when merging errors.
// If multiple errors have `errors`, the parent's errors are prepended.
// `error.errors[*].cause` are recursed.
// We do not merge `error.errors` into a single error:
// - Because:
// - Unlike `error.cause`, those are separate errors, which should remain so
// - Each error's message and stack trace should be kept as is, otherwise:
// - Those could be very long if `error.errors` is large
// - Those could lead to confusing stack traces
// - I.e. it is the responsibility of the consumers to recurse and handle
// `error.errors`
const setAggregate = function (parent, parentErrors) {
if (parentErrors !== undefined) {
setErrorProperty(parent, 'errors', parentErrors)
}
}

const mergeAggregate = function (mergedError, parentErrors, child) {
const childErrors = getAggregateErrors(child)

if (parentErrors === undefined && childErrors === undefined) {
return
}

const errors = getMergedErrors(parentErrors, childErrors)
setErrorProperty(mergedError, 'errors', errors)
}

const getAggregateErrors = function (error) {
return Array.isArray(error.errors)
? error.errors.map(mergeErrorCause)
: undefined
}

const getMergedErrors = function (parentErrors, childErrors) {
if (parentErrors === undefined) {
return childErrors
}

if (childErrors === undefined) {
return parentErrors
}

return [...childErrors, ...parentErrors]
}

0 comments on commit c0573b3

Please sign in to comment.