Log errors when tasks fail

* Log errors that occur when running a task
* Use a child logger when initalising a new TaskWorker to include the task id with any logs.

Signed-off-by: Alex Crome <afscrome@users.noreply.github.com>
This commit is contained in:
Alex Crome
2022-05-27 14:46:15 +01:00
parent 2bd303dced
commit 7f108513b8
4 changed files with 37 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-tasks': patch
---
Add error logging when a background task throws an error rather than silently swallowing it.
@@ -57,7 +57,12 @@ export class PluginTaskSchedulerImpl implements PluginTaskScheduler {
if (scope === 'global') {
const knex = await this.databaseFactory();
const worker = new TaskWorker(task.id, task.fn, knex, this.logger);
const worker = new TaskWorker(
task.id,
task.fn,
knex,
this.logger.child({ task: task.id }),
);
await worker.start(
{
@@ -119,6 +119,31 @@ describe('TaskWorker', () => {
60_000,
);
it.each(databases.eachSupportedId())(
'logs error when the task throws, %p',
async databaseId => {
const knex = await databases.init(databaseId);
await migrateBackendTasks(knex);
jest.spyOn(logger, 'error');
const fn = jest.fn().mockRejectedValue(new Error('failed'));
const settings: TaskSettingsV2 = {
version: 2,
initialDelayDuration: undefined,
cadence: '* * * * * *',
timeoutAfterDuration: Duration.fromMillis(60000).toISO(),
};
const checkFrequency = Duration.fromObject({ milliseconds: 100 });
const worker = new TaskWorker('task1', fn, knex, logger, checkFrequency);
worker.start(settings);
await waitForExpect(() => {
expect(logger.error).toBeCalled();
});
},
60_000,
);
it.each(databases.eachSupportedId())(
'runs tasks more than once even when the task throws, %p',
async databaseId => {
@@ -145,6 +145,7 @@ export class TaskWorker {
await this.fn(taskAbortController.signal);
taskAbortController.abort(); // releases resources
} catch (e) {
this.logger.error(e);
await this.tryReleaseTask(ticket, taskSettings);
return { result: 'failed' };
} finally {