errors: add toError utility and migrate assertError usages

Add a `toError` utility function to `@backstage/errors` that converts
unknown values to `ErrorLike` objects. If the value is already error-like
it is returned as-is. Strings are used directly as the error message, and
other values are stringified with a fallback to JSON.stringify to avoid
unhelpful `[object Object]` messages.

Non-error causes passed to `CustomErrorBase` are now converted and stored
using `toError` rather than discarded. Existing `assertError` call sites
across the codebase are migrated to `toError`.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-04-03 01:33:34 +02:00
parent 3cdf048f77
commit b2319ffe45
70 changed files with 400 additions and 345 deletions
@@ -16,7 +16,7 @@
import { AuditorService, LoggerService } from '@backstage/backend-plugin-api';
import type { MetricsService } from '@backstage/backend-plugin-api/alpha';
import { assertError, InputError, stringifyError } from '@backstage/errors';
import { InputError, stringifyError, toError } from '@backstage/errors';
import { ScmIntegrations } from '@backstage/integration';
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
import {
@@ -228,12 +228,12 @@ export class TaskWorker {
await task.complete('completed', { output });
await auditorEvent?.success();
} catch (error) {
assertError(error);
const err = toError(error);
await auditorEvent?.fail({
error,
error: err,
});
await task.complete('failed', {
error: { name: error.name, message: error.message },
error: { name: err.name, message: err.message },
});
}
}
@@ -27,7 +27,7 @@ import {
stringifyEntityRef,
} from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { assertError, InputError, NotFoundError } from '@backstage/errors';
import { InputError, NotFoundError, toError } from '@backstage/errors';
import { CatalogService } from '@backstage/plugin-catalog-node';
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
import fs from 'fs-extra';
@@ -47,13 +47,13 @@ export async function getWorkingDirectory(
await fs.access(workingDirectory, fs.constants.F_OK | fs.constants.W_OK);
logger.info(`using working directory: ${workingDirectory}`);
} catch (err) {
assertError(err);
const error = toError(err);
logger.error(
`working directory ${workingDirectory} ${
err.code === 'ENOENT' ? 'does not exist' : 'is not writable'
error.code === 'ENOENT' ? 'does not exist' : 'is not writable'
}`,
);
throw err;
throw error;
}
return workingDirectory;
}