141 lines
4.1 KiB
TypeScript
141 lines
4.1 KiB
TypeScript
import type {
|
|
TaskRunExecutionResult,
|
|
TaskRunFailedExecutionResult,
|
|
TaskRunSuccessfulExecutionResult,
|
|
} from "@trigger.dev/core/v3";
|
|
import { TaskRunError, TaskRunErrorCodes } from "@trigger.dev/core/v3";
|
|
|
|
import type {
|
|
BatchTaskRunItemStatus as BatchTaskRunItemStatusType,
|
|
TaskRun,
|
|
TaskRunAttempt,
|
|
TaskRunStatus as TaskRunStatusType,
|
|
} from "@trigger.dev/database";
|
|
|
|
import { assertNever } from "assert-never";
|
|
import { BatchTaskRunItemStatus, TaskRunAttemptStatus, TaskRunStatus } from "~/database-types";
|
|
import { logger } from "~/services/logger.server";
|
|
|
|
const SUCCESSFUL_STATUSES = [TaskRunStatus.COMPLETED_SUCCESSFULLY];
|
|
const FAILURE_STATUSES = [
|
|
TaskRunStatus.CANCELED,
|
|
TaskRunStatus.INTERRUPTED,
|
|
TaskRunStatus.COMPLETED_WITH_ERRORS,
|
|
TaskRunStatus.SYSTEM_FAILURE,
|
|
TaskRunStatus.CRASHED,
|
|
];
|
|
|
|
export type TaskRunWithAttempts = TaskRun & {
|
|
attempts: TaskRunAttempt[];
|
|
};
|
|
|
|
export function executionResultForTaskRun(
|
|
taskRun: TaskRunWithAttempts
|
|
): TaskRunExecutionResult | undefined {
|
|
if (SUCCESSFUL_STATUSES.includes(taskRun.status)) {
|
|
// find the last attempt that was successful
|
|
const attempt = taskRun.attempts.find((a) => a.status === TaskRunAttemptStatus.COMPLETED);
|
|
|
|
if (!attempt) {
|
|
logger.error("Task run is successful but no successful attempt found", {
|
|
taskRunId: taskRun.id,
|
|
taskRunStatus: taskRun.status,
|
|
taskRunAttempts: taskRun.attempts.map((a) => a.status),
|
|
});
|
|
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
ok: true,
|
|
id: taskRun.friendlyId,
|
|
taskIdentifier: taskRun.taskIdentifier,
|
|
output: attempt.output ?? undefined,
|
|
outputType: attempt.outputType,
|
|
} satisfies TaskRunSuccessfulExecutionResult;
|
|
}
|
|
|
|
if (FAILURE_STATUSES.includes(taskRun.status)) {
|
|
if (taskRun.status === TaskRunStatus.CANCELED) {
|
|
return {
|
|
ok: false,
|
|
id: taskRun.friendlyId,
|
|
taskIdentifier: taskRun.taskIdentifier,
|
|
error: {
|
|
type: "INTERNAL_ERROR",
|
|
code: TaskRunErrorCodes.TASK_RUN_CANCELLED,
|
|
},
|
|
} satisfies TaskRunFailedExecutionResult;
|
|
}
|
|
|
|
const attempt = taskRun.attempts.find((a) => a.status === TaskRunAttemptStatus.FAILED);
|
|
|
|
if (!attempt) {
|
|
logger.error("Task run is failed but no failed attempt found", {
|
|
taskRunId: taskRun.id,
|
|
taskRunStatus: taskRun.status,
|
|
taskRunAttempts: taskRun.attempts.map((a) => a.status),
|
|
});
|
|
|
|
return undefined;
|
|
}
|
|
|
|
const error = TaskRunError.safeParse(attempt.error);
|
|
|
|
if (!error.success) {
|
|
logger.error("Failed to parse error from failed task run attempt", {
|
|
taskRunId: taskRun.id,
|
|
taskRunStatus: taskRun.status,
|
|
taskRunAttempts: taskRun.attempts.map((a) => a.status),
|
|
error: attempt.error,
|
|
});
|
|
|
|
return {
|
|
ok: false,
|
|
id: taskRun.friendlyId,
|
|
taskIdentifier: taskRun.taskIdentifier,
|
|
error: {
|
|
type: "INTERNAL_ERROR",
|
|
code: TaskRunErrorCodes.CONFIGURED_INCORRECTLY,
|
|
},
|
|
} satisfies TaskRunFailedExecutionResult;
|
|
}
|
|
|
|
return {
|
|
ok: false,
|
|
id: taskRun.friendlyId,
|
|
taskIdentifier: taskRun.taskIdentifier,
|
|
error: error.data,
|
|
} satisfies TaskRunFailedExecutionResult;
|
|
}
|
|
}
|
|
|
|
export function batchTaskRunItemStatusForRunStatus(
|
|
status: TaskRunStatusType
|
|
): BatchTaskRunItemStatusType {
|
|
switch (status) {
|
|
case TaskRunStatus.COMPLETED_SUCCESSFULLY:
|
|
return BatchTaskRunItemStatus.COMPLETED;
|
|
case TaskRunStatus.CANCELED:
|
|
case TaskRunStatus.INTERRUPTED:
|
|
case TaskRunStatus.COMPLETED_WITH_ERRORS:
|
|
case TaskRunStatus.SYSTEM_FAILURE:
|
|
case TaskRunStatus.CRASHED:
|
|
case TaskRunStatus.EXPIRED:
|
|
case TaskRunStatus.TIMED_OUT:
|
|
return BatchTaskRunItemStatus.FAILED;
|
|
case TaskRunStatus.PENDING:
|
|
case TaskRunStatus.PENDING_VERSION:
|
|
case TaskRunStatus.WAITING_FOR_DEPLOY:
|
|
case TaskRunStatus.WAITING_TO_RESUME:
|
|
case TaskRunStatus.RETRYING_AFTER_FAILURE:
|
|
case TaskRunStatus.DEQUEUED:
|
|
case TaskRunStatus.EXECUTING:
|
|
case TaskRunStatus.PAUSED:
|
|
case TaskRunStatus.DELAYED:
|
|
return BatchTaskRunItemStatus.PENDING;
|
|
default:
|
|
assertNever(status);
|
|
}
|
|
}
|