|
| 1 | +import { |
| 2 | + DeploymentErrorData, |
| 3 | + TaskMetadataFailedToParseData, |
| 4 | + groupTaskMetadataIssuesByTask, |
| 5 | +} from "@trigger.dev/core/v3"; |
1 | 6 | import { WorkerDeployment, WorkerDeploymentStatus } from "@trigger.dev/database"; |
| 7 | +import { z } from "zod"; |
2 | 8 | import { PrismaClient, prisma } from "~/db.server"; |
3 | 9 | import { Organization } from "~/models/organization.server"; |
4 | 10 | import { Project } from "~/models/project.server"; |
5 | 11 | import { User } from "~/models/user.server"; |
| 12 | +import { safeJsonParse } from "~/utils/json"; |
6 | 13 | import { getUsername } from "~/utils/username"; |
7 | 14 |
|
8 | 15 | export class DeploymentPresenter { |
@@ -51,6 +58,7 @@ export class DeploymentPresenter { |
51 | 58 | id: true, |
52 | 59 | shortCode: true, |
53 | 60 | version: true, |
| 61 | + errorData: true, |
54 | 62 | environment: { |
55 | 63 | select: { |
56 | 64 | id: true, |
@@ -120,7 +128,81 @@ export class DeploymentPresenter { |
120 | 128 | userName: getUsername(deployment.environment.orgMember?.user), |
121 | 129 | }, |
122 | 130 | deployedBy: deployment.triggeredBy, |
| 131 | + errorData: this.#prepareErrorData(deployment.errorData), |
123 | 132 | }, |
124 | 133 | }; |
125 | 134 | } |
| 135 | + |
| 136 | + #prepareErrorData(errorData: WorkerDeployment["errorData"]) { |
| 137 | + if (!errorData) { |
| 138 | + return; |
| 139 | + } |
| 140 | + |
| 141 | + const parsedErrorData = DeploymentErrorData.safeParse(errorData); |
| 142 | + |
| 143 | + if (!parsedErrorData.success) { |
| 144 | + return; |
| 145 | + } |
| 146 | + |
| 147 | + if (parsedErrorData.data.name === "TaskMetadataParseError") { |
| 148 | + const errorJson = safeJsonParse(parsedErrorData.data.stack); |
| 149 | + |
| 150 | + if (errorJson) { |
| 151 | + const parsedError = TaskMetadataFailedToParseData.safeParse(errorJson); |
| 152 | + |
| 153 | + if (parsedError.success) { |
| 154 | + return { |
| 155 | + name: parsedErrorData.data.name, |
| 156 | + message: parsedErrorData.data.message, |
| 157 | + stack: createTaskMetadataFailedErrorStack(parsedError.data), |
| 158 | + }; |
| 159 | + } else { |
| 160 | + return { |
| 161 | + name: parsedErrorData.data.name, |
| 162 | + message: parsedErrorData.data.message, |
| 163 | + }; |
| 164 | + } |
| 165 | + } else { |
| 166 | + return { |
| 167 | + name: parsedErrorData.data.name, |
| 168 | + message: parsedErrorData.data.message, |
| 169 | + }; |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + return { |
| 174 | + name: parsedErrorData.data.name, |
| 175 | + message: parsedErrorData.data.message, |
| 176 | + stack: parsedErrorData.data.stack, |
| 177 | + }; |
| 178 | + } |
| 179 | +} |
| 180 | + |
| 181 | +function createTaskMetadataFailedErrorStack( |
| 182 | + data: z.infer<typeof TaskMetadataFailedToParseData> |
| 183 | +): string { |
| 184 | + const stack = []; |
| 185 | + |
| 186 | + const groupedIssues = groupTaskMetadataIssuesByTask(data.tasks, data.zodIssues); |
| 187 | + |
| 188 | + for (const key in groupedIssues) { |
| 189 | + const taskWithIssues = groupedIssues[key]; |
| 190 | + |
| 191 | + if (!taskWithIssues) { |
| 192 | + continue; |
| 193 | + } |
| 194 | + |
| 195 | + stack.push("\n"); |
| 196 | + stack.push(` ❯ ${taskWithIssues.exportName} in ${taskWithIssues.filePath}`); |
| 197 | + |
| 198 | + for (const issue of taskWithIssues.issues) { |
| 199 | + if (issue.path) { |
| 200 | + stack.push(` x ${issue.path} ${issue.message}`); |
| 201 | + } else { |
| 202 | + stack.push(` x ${issue.message}`); |
| 203 | + } |
| 204 | + } |
| 205 | + } |
| 206 | + |
| 207 | + return stack.join("\n"); |
126 | 208 | } |
0 commit comments