@milaboratories/pl-errors 1.1.58 → 1.1.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/parsed_error.cjs +32 -30
- package/dist/parsed_error.cjs.map +1 -1
- package/dist/parsed_error.d.ts +1 -1
- package/dist/parsed_error.d.ts.map +1 -1
- package/dist/parsed_error.js +32 -30
- package/dist/parsed_error.js.map +1 -1
- package/package.json +19 -18
- package/src/index.ts +1 -1
- package/src/parsed_error.test.ts +72 -39
- package/src/parsed_error.ts +48 -53
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./parsed_error";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/parsed_error.cjs
CHANGED
|
@@ -11,14 +11,14 @@ class PlQuickJSError extends Error {
|
|
|
11
11
|
fullMessage;
|
|
12
12
|
constructor(quickJSError, cause) {
|
|
13
13
|
super(`PlQuickJSError: ${cause.message}`, { cause });
|
|
14
|
-
this.name =
|
|
14
|
+
this.name = "PlQuickJSError";
|
|
15
15
|
// QuickJS wraps the error with the name and the message,
|
|
16
16
|
// but we need another format.
|
|
17
17
|
let stack = tsHelpers.notEmpty(quickJSError.stack);
|
|
18
|
-
stack = stack.replace(quickJSError.message,
|
|
19
|
-
stack = stack.replace(tsHelpers.notEmpty(cause.message),
|
|
18
|
+
stack = stack.replace(quickJSError.message, "");
|
|
19
|
+
stack = stack.replace(tsHelpers.notEmpty(cause.message), "");
|
|
20
20
|
this.stack = stack;
|
|
21
|
-
const causeMsg =
|
|
21
|
+
const causeMsg = "fullMessage" in cause && typeof cause.fullMessage === "string"
|
|
22
22
|
? cause.fullMessage
|
|
23
23
|
: cause.message;
|
|
24
24
|
this.fullMessage = `PlQuickJSError: ${causeMsg}
|
|
@@ -51,8 +51,8 @@ class PlErrorReport extends Error {
|
|
|
51
51
|
errors,
|
|
52
52
|
/** Optional info about a resource where the error happened. */
|
|
53
53
|
fieldName, resource, resourceType) {
|
|
54
|
-
const errorMessages = errors.map((e) => e.message).join(
|
|
55
|
-
const errorFullMessages = errors.map((e) => e.fullMessage).join(
|
|
54
|
+
const errorMessages = errors.map((e) => e.message).join("\n\n");
|
|
55
|
+
const errorFullMessages = errors.map((e) => e.fullMessage).join("\n\n");
|
|
56
56
|
super(`PlErrorReport: ${errorMessages}`);
|
|
57
57
|
this.rawBackendMessage = rawBackendMessage;
|
|
58
58
|
this.plErrorType = plErrorType;
|
|
@@ -61,11 +61,11 @@ class PlErrorReport extends Error {
|
|
|
61
61
|
this.fieldName = fieldName;
|
|
62
62
|
this.resource = resource;
|
|
63
63
|
this.resourceType = resourceType;
|
|
64
|
-
this.name =
|
|
65
|
-
const rt = this.resourceType ? `${plClient.resourceTypeToString(this.resourceType)},` :
|
|
66
|
-
const r = this.resource ? plClient.resourceIdToString(this.resource) :
|
|
67
|
-
const f = this.fieldName ? `/${this.fieldName}` :
|
|
68
|
-
const errType = this.plErrorType ? `error type: ${this.plErrorType}` :
|
|
64
|
+
this.name = "PlErrorReport";
|
|
65
|
+
const rt = this.resourceType ? `${plClient.resourceTypeToString(this.resourceType)},` : "";
|
|
66
|
+
const r = this.resource ? plClient.resourceIdToString(this.resource) : "";
|
|
67
|
+
const f = this.fieldName ? `/${this.fieldName}` : "";
|
|
68
|
+
const errType = this.plErrorType ? `error type: ${this.plErrorType}` : "";
|
|
69
69
|
this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
|
|
70
70
|
${errType}
|
|
71
71
|
${errorFullMessages}
|
|
@@ -81,7 +81,7 @@ class PlInternalError extends Error {
|
|
|
81
81
|
constructor(message) {
|
|
82
82
|
super(message);
|
|
83
83
|
this.message = message;
|
|
84
|
-
this.name =
|
|
84
|
+
this.name = "PlInternalError";
|
|
85
85
|
this.fullMessage = `PlInternalError: ${message}`;
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -107,7 +107,7 @@ ${tengoStacktrace}
|
|
|
107
107
|
this.templateName = templateName;
|
|
108
108
|
this.tengoMessage = tengoMessage;
|
|
109
109
|
this.tengoStacktrace = tengoStacktrace;
|
|
110
|
-
this.name =
|
|
110
|
+
this.name = "PlTengoError";
|
|
111
111
|
this.fullMessage = `${msg}
|
|
112
112
|
raw message:
|
|
113
113
|
${this.rawBackendMessage}
|
|
@@ -137,7 +137,7 @@ ${stdout}`;
|
|
|
137
137
|
this.exitCode = exitCode;
|
|
138
138
|
this.stdout = stdout;
|
|
139
139
|
this.workingDirectory = workingDirectory;
|
|
140
|
-
this.name =
|
|
140
|
+
this.name = "PlRunnerError";
|
|
141
141
|
this.fullMessage = `
|
|
142
142
|
${msg}
|
|
143
143
|
raw message:
|
|
@@ -156,7 +156,7 @@ class PlMonetizationError extends PlRunnerError {
|
|
|
156
156
|
${this.stdout}
|
|
157
157
|
`;
|
|
158
158
|
this.message = msg;
|
|
159
|
-
this.name =
|
|
159
|
+
this.name = "PlMonetizationError";
|
|
160
160
|
this.fullMessage = `
|
|
161
161
|
${msg}
|
|
162
162
|
command: ${this.commandName}
|
|
@@ -171,10 +171,12 @@ ${this.rawBackendMessage}
|
|
|
171
171
|
/**
|
|
172
172
|
* How the Pl backend represents an error.
|
|
173
173
|
*/
|
|
174
|
-
const backendErrorSchema = zod.z
|
|
175
|
-
|
|
174
|
+
const backendErrorSchema = zod.z
|
|
175
|
+
.object({
|
|
176
|
+
errorType: zod.z.string().default(""),
|
|
176
177
|
message: zod.z.string(),
|
|
177
|
-
})
|
|
178
|
+
})
|
|
179
|
+
.passthrough();
|
|
178
180
|
/**
|
|
179
181
|
* Parses a Pl error and suberrors from the Pl backend.
|
|
180
182
|
*/
|
|
@@ -193,34 +195,34 @@ function parsePlError(error, resource, resourceType, field) {
|
|
|
193
195
|
function parseSubErrors(message) {
|
|
194
196
|
// the state of this reducing function
|
|
195
197
|
const state = {
|
|
196
|
-
stage:
|
|
198
|
+
stage: "initial",
|
|
197
199
|
value: [],
|
|
198
200
|
result: [],
|
|
199
201
|
};
|
|
200
|
-
for (const line of message.split(
|
|
201
|
-
if (state.stage ==
|
|
202
|
+
for (const line of message.split("\n")) {
|
|
203
|
+
if (state.stage == "initial") {
|
|
202
204
|
// we need initial stage because apparently the first line
|
|
203
205
|
// of the error doesn't have [I], but is a path line.
|
|
204
|
-
state.stage =
|
|
206
|
+
state.stage = "path";
|
|
205
207
|
}
|
|
206
|
-
else if (state.stage ==
|
|
207
|
-
else if (state.stage ==
|
|
208
|
-
state.stage =
|
|
208
|
+
else if (state.stage == "path" && line.startsWith("---")) ;
|
|
209
|
+
else if (state.stage == "path" && !isPath(line)) {
|
|
210
|
+
state.stage = "message";
|
|
209
211
|
}
|
|
210
|
-
else if (state.stage ==
|
|
211
|
-
state.stage =
|
|
212
|
-
const text = state.value.join(
|
|
212
|
+
else if (state.stage == "message" && isPath(line)) {
|
|
213
|
+
state.stage = "path";
|
|
214
|
+
const text = state.value.join("\n");
|
|
213
215
|
state.result.push(parseCoreError(text));
|
|
214
216
|
state.value = [];
|
|
215
217
|
}
|
|
216
218
|
state.value.push(line);
|
|
217
219
|
}
|
|
218
|
-
const text = state.value.join(
|
|
220
|
+
const text = state.value.join("\n");
|
|
219
221
|
state.result.push(parseCoreError(text));
|
|
220
222
|
return state.result;
|
|
221
223
|
}
|
|
222
224
|
function isPath(line) {
|
|
223
|
-
for (const fieldType of [
|
|
225
|
+
for (const fieldType of ["U", "I", "O", "S", "OTW", "D", "MTW"]) {
|
|
224
226
|
if (line.startsWith(`[${fieldType}]`))
|
|
225
227
|
return true;
|
|
226
228
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed_error.cjs","sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from 'zod';\nimport type { ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport { resourceIdToString, resourceTypeToString } from '@milaboratories/pl-client';\nimport { notEmpty } from '@milaboratories/ts-helpers';\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(\n quickJSError: Error,\n cause: Error,\n ) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = 'PlQuickJSError';\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, '');\n stack = stack.replace(notEmpty(cause.message), '');\n\n this.stack = stack;\n\n const causeMsg = 'fullMessage' in cause && typeof cause.fullMessage === 'string'\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join('\\n\\n');\n const errorFullMessages = errors.map((e) => e.fullMessage).join('\\n\\n');\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = 'PlErrorReport';\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : '';\n const r = this.resource ? resourceIdToString(this.resource) : '';\n const f = this.fieldName ? `/${this.fieldName}` : '';\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : '';\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError =\n | PlInternalError\n | PlTengoError\n | PlRunnerError\n | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(\n public readonly message: string,\n ) {\n super(message);\n this.name = 'PlInternalError';\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = 'PlTengoError';\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = 'PlRunnerError';\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = 'PlMonetizationError';\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z.object({\n errorType: z.string().default(''),\n message: z.string(),\n}).passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: 'initial' as 'initial' | 'path' | 'message',\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split('\\n')) {\n if (state.stage == 'initial') {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = 'path';\n } else if (state.stage == 'path' && line.startsWith('---')) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == 'path' && !isPath(line)) {\n state.stage = 'message';\n } else if (state.stage == 'message' && isPath(line)) {\n state.stage = 'path';\n const text = state.value.join('\\n');\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join('\\n');\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of ['U', 'I', 'O', 'S', 'OTW', 'D', 'MTW']) {\n if (line.startsWith(`[${fieldType}]`))\n return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex = /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex = /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"names":["notEmpty","resourceTypeToString","resourceIdToString","z"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parsed_error.cjs","sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from \"zod\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport { resourceIdToString, resourceTypeToString } from \"@milaboratories/pl-client\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(quickJSError: Error, cause: Error) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = \"PlQuickJSError\";\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, \"\");\n stack = stack.replace(notEmpty(cause.message), \"\");\n\n this.stack = stack;\n\n const causeMsg =\n \"fullMessage\" in cause && typeof cause.fullMessage === \"string\"\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join(\"\\n\\n\");\n const errorFullMessages = errors.map((e) => e.fullMessage).join(\"\\n\\n\");\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = \"PlErrorReport\";\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : \"\";\n const r = this.resource ? resourceIdToString(this.resource) : \"\";\n const f = this.fieldName ? `/${this.fieldName}` : \"\";\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : \"\";\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(public readonly message: string) {\n super(message);\n this.name = \"PlInternalError\";\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = \"PlTengoError\";\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = \"PlRunnerError\";\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = \"PlMonetizationError\";\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z\n .object({\n errorType: z.string().default(\"\"),\n message: z.string(),\n })\n .passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: \"initial\" as \"initial\" | \"path\" | \"message\",\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split(\"\\n\")) {\n if (state.stage == \"initial\") {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = \"path\";\n } else if (state.stage == \"path\" && line.startsWith(\"---\")) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == \"path\" && !isPath(line)) {\n state.stage = \"message\";\n } else if (state.stage == \"message\" && isPath(line)) {\n state.stage = \"path\";\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of [\"U\", \"I\", \"O\", \"S\", \"OTW\", \"D\", \"MTW\"]) {\n if (line.startsWith(`[${fieldType}]`)) return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex =\n /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex =\n /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"names":["notEmpty","resourceTypeToString","resourceIdToString","z"],"mappings":"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"}
|
package/dist/parsed_error.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */
|
|
2
|
-
import type { ResourceId, ResourceType } from
|
|
2
|
+
import type { ResourceId, ResourceType } from "@milaboratories/pl-client";
|
|
3
3
|
/** The error that comes from QuickJS. */
|
|
4
4
|
export declare class PlQuickJSError extends Error {
|
|
5
5
|
stack: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed_error.d.ts","sourceRoot":"","sources":["../src/parsed_error.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAG/E,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAI1E,yCAAyC;AACzC,qBAAa,cAAe,SAAQ,KAAK;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"parsed_error.d.ts","sourceRoot":"","sources":["../src/parsed_error.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAG/E,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAI1E,yCAAyC;AACzC,qBAAa,cAAe,SAAQ,KAAK;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;gBAEf,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;CAsB9C;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAIpC,wCAAwC;aACxB,iBAAiB,EAAE,MAAM;IAEzC,sDAAsD;aACtC,WAAW,EAAE,MAAM;IAEnC,2EAA2E;aAC3D,SAAS,EAAE,MAAM;IAEjC,0EAA0E;aAC1D,MAAM,EAAE,WAAW,EAAE;IAErC,+DAA+D;aAC/C,SAAS,CAAC,EAAE,MAAM;aAClB,QAAQ,CAAC,EAAE,UAAU;aACrB,YAAY,CAAC,EAAE,YAAY;IAlB7C,SAAgB,WAAW,EAAE,MAAM,CAAC;;IAGlC,wCAAwC;IACxB,iBAAiB,EAAE,MAAM;IAEzC,sDAAsD;IACtC,WAAW,EAAE,MAAM;IAEnC,2EAA2E;IAC3D,SAAS,EAAE,MAAM;IAEjC,0EAA0E;IAC1D,MAAM,EAAE,WAAW,EAAE;IAErC,+DAA+D;IAC/C,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,QAAQ,CAAC,EAAE,UAAU,YAAA,EACrB,YAAY,CAAC,EAAE,YAAY,YAAA;CAkB9C;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,YAAY,GAAG,aAAa,GAAG,mBAAmB,CAAC;AAE/F;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAEZ,OAAO,EAAE,MAAM;IAD3C,SAAgB,WAAW,EAAE,MAAM,CAAC;gBACR,OAAO,EAAE,MAAM;CAK5C;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;aAInB,iBAAiB,EAAE,MAAM;aACzB,YAAY,EAAE,MAAM;aACpB,YAAY,EAAE,MAAM;aACpB,eAAe,EAAE,MAAM;IANzC,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAGlB,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM;CAkB1C;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAIpB,iBAAiB,EAAE,MAAM;aACzB,WAAW,EAAE,MAAM;aACnB,QAAQ,EAAE,MAAM;aAChB,MAAM,EAAE,MAAM;aACd,gBAAgB,EAAE,MAAM;IAP1C,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAGlB,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM;CAiB3C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,aAAa;IACpD,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAElC,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM;CAoB3B;AAYD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,UAAU,EACrB,YAAY,CAAC,EAAE,YAAY,EAC3B,KAAK,CAAC,EAAE,MAAM,GACb,aAAa,CAkBf;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CAgC7D"}
|
package/dist/parsed_error.js
CHANGED
|
@@ -9,14 +9,14 @@ class PlQuickJSError extends Error {
|
|
|
9
9
|
fullMessage;
|
|
10
10
|
constructor(quickJSError, cause) {
|
|
11
11
|
super(`PlQuickJSError: ${cause.message}`, { cause });
|
|
12
|
-
this.name =
|
|
12
|
+
this.name = "PlQuickJSError";
|
|
13
13
|
// QuickJS wraps the error with the name and the message,
|
|
14
14
|
// but we need another format.
|
|
15
15
|
let stack = notEmpty(quickJSError.stack);
|
|
16
|
-
stack = stack.replace(quickJSError.message,
|
|
17
|
-
stack = stack.replace(notEmpty(cause.message),
|
|
16
|
+
stack = stack.replace(quickJSError.message, "");
|
|
17
|
+
stack = stack.replace(notEmpty(cause.message), "");
|
|
18
18
|
this.stack = stack;
|
|
19
|
-
const causeMsg =
|
|
19
|
+
const causeMsg = "fullMessage" in cause && typeof cause.fullMessage === "string"
|
|
20
20
|
? cause.fullMessage
|
|
21
21
|
: cause.message;
|
|
22
22
|
this.fullMessage = `PlQuickJSError: ${causeMsg}
|
|
@@ -49,8 +49,8 @@ class PlErrorReport extends Error {
|
|
|
49
49
|
errors,
|
|
50
50
|
/** Optional info about a resource where the error happened. */
|
|
51
51
|
fieldName, resource, resourceType) {
|
|
52
|
-
const errorMessages = errors.map((e) => e.message).join(
|
|
53
|
-
const errorFullMessages = errors.map((e) => e.fullMessage).join(
|
|
52
|
+
const errorMessages = errors.map((e) => e.message).join("\n\n");
|
|
53
|
+
const errorFullMessages = errors.map((e) => e.fullMessage).join("\n\n");
|
|
54
54
|
super(`PlErrorReport: ${errorMessages}`);
|
|
55
55
|
this.rawBackendMessage = rawBackendMessage;
|
|
56
56
|
this.plErrorType = plErrorType;
|
|
@@ -59,11 +59,11 @@ class PlErrorReport extends Error {
|
|
|
59
59
|
this.fieldName = fieldName;
|
|
60
60
|
this.resource = resource;
|
|
61
61
|
this.resourceType = resourceType;
|
|
62
|
-
this.name =
|
|
63
|
-
const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` :
|
|
64
|
-
const r = this.resource ? resourceIdToString(this.resource) :
|
|
65
|
-
const f = this.fieldName ? `/${this.fieldName}` :
|
|
66
|
-
const errType = this.plErrorType ? `error type: ${this.plErrorType}` :
|
|
62
|
+
this.name = "PlErrorReport";
|
|
63
|
+
const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : "";
|
|
64
|
+
const r = this.resource ? resourceIdToString(this.resource) : "";
|
|
65
|
+
const f = this.fieldName ? `/${this.fieldName}` : "";
|
|
66
|
+
const errType = this.plErrorType ? `error type: ${this.plErrorType}` : "";
|
|
67
67
|
this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
|
|
68
68
|
${errType}
|
|
69
69
|
${errorFullMessages}
|
|
@@ -79,7 +79,7 @@ class PlInternalError extends Error {
|
|
|
79
79
|
constructor(message) {
|
|
80
80
|
super(message);
|
|
81
81
|
this.message = message;
|
|
82
|
-
this.name =
|
|
82
|
+
this.name = "PlInternalError";
|
|
83
83
|
this.fullMessage = `PlInternalError: ${message}`;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -105,7 +105,7 @@ ${tengoStacktrace}
|
|
|
105
105
|
this.templateName = templateName;
|
|
106
106
|
this.tengoMessage = tengoMessage;
|
|
107
107
|
this.tengoStacktrace = tengoStacktrace;
|
|
108
|
-
this.name =
|
|
108
|
+
this.name = "PlTengoError";
|
|
109
109
|
this.fullMessage = `${msg}
|
|
110
110
|
raw message:
|
|
111
111
|
${this.rawBackendMessage}
|
|
@@ -135,7 +135,7 @@ ${stdout}`;
|
|
|
135
135
|
this.exitCode = exitCode;
|
|
136
136
|
this.stdout = stdout;
|
|
137
137
|
this.workingDirectory = workingDirectory;
|
|
138
|
-
this.name =
|
|
138
|
+
this.name = "PlRunnerError";
|
|
139
139
|
this.fullMessage = `
|
|
140
140
|
${msg}
|
|
141
141
|
raw message:
|
|
@@ -154,7 +154,7 @@ class PlMonetizationError extends PlRunnerError {
|
|
|
154
154
|
${this.stdout}
|
|
155
155
|
`;
|
|
156
156
|
this.message = msg;
|
|
157
|
-
this.name =
|
|
157
|
+
this.name = "PlMonetizationError";
|
|
158
158
|
this.fullMessage = `
|
|
159
159
|
${msg}
|
|
160
160
|
command: ${this.commandName}
|
|
@@ -169,10 +169,12 @@ ${this.rawBackendMessage}
|
|
|
169
169
|
/**
|
|
170
170
|
* How the Pl backend represents an error.
|
|
171
171
|
*/
|
|
172
|
-
const backendErrorSchema = z
|
|
173
|
-
|
|
172
|
+
const backendErrorSchema = z
|
|
173
|
+
.object({
|
|
174
|
+
errorType: z.string().default(""),
|
|
174
175
|
message: z.string(),
|
|
175
|
-
})
|
|
176
|
+
})
|
|
177
|
+
.passthrough();
|
|
176
178
|
/**
|
|
177
179
|
* Parses a Pl error and suberrors from the Pl backend.
|
|
178
180
|
*/
|
|
@@ -191,34 +193,34 @@ function parsePlError(error, resource, resourceType, field) {
|
|
|
191
193
|
function parseSubErrors(message) {
|
|
192
194
|
// the state of this reducing function
|
|
193
195
|
const state = {
|
|
194
|
-
stage:
|
|
196
|
+
stage: "initial",
|
|
195
197
|
value: [],
|
|
196
198
|
result: [],
|
|
197
199
|
};
|
|
198
|
-
for (const line of message.split(
|
|
199
|
-
if (state.stage ==
|
|
200
|
+
for (const line of message.split("\n")) {
|
|
201
|
+
if (state.stage == "initial") {
|
|
200
202
|
// we need initial stage because apparently the first line
|
|
201
203
|
// of the error doesn't have [I], but is a path line.
|
|
202
|
-
state.stage =
|
|
204
|
+
state.stage = "path";
|
|
203
205
|
}
|
|
204
|
-
else if (state.stage ==
|
|
205
|
-
else if (state.stage ==
|
|
206
|
-
state.stage =
|
|
206
|
+
else if (state.stage == "path" && line.startsWith("---")) ;
|
|
207
|
+
else if (state.stage == "path" && !isPath(line)) {
|
|
208
|
+
state.stage = "message";
|
|
207
209
|
}
|
|
208
|
-
else if (state.stage ==
|
|
209
|
-
state.stage =
|
|
210
|
-
const text = state.value.join(
|
|
210
|
+
else if (state.stage == "message" && isPath(line)) {
|
|
211
|
+
state.stage = "path";
|
|
212
|
+
const text = state.value.join("\n");
|
|
211
213
|
state.result.push(parseCoreError(text));
|
|
212
214
|
state.value = [];
|
|
213
215
|
}
|
|
214
216
|
state.value.push(line);
|
|
215
217
|
}
|
|
216
|
-
const text = state.value.join(
|
|
218
|
+
const text = state.value.join("\n");
|
|
217
219
|
state.result.push(parseCoreError(text));
|
|
218
220
|
return state.result;
|
|
219
221
|
}
|
|
220
222
|
function isPath(line) {
|
|
221
|
-
for (const fieldType of [
|
|
223
|
+
for (const fieldType of ["U", "I", "O", "S", "OTW", "D", "MTW"]) {
|
|
222
224
|
if (line.startsWith(`[${fieldType}]`))
|
|
223
225
|
return true;
|
|
224
226
|
}
|
package/dist/parsed_error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed_error.js","sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from 'zod';\nimport type { ResourceId, ResourceType } from '@milaboratories/pl-client';\nimport { resourceIdToString, resourceTypeToString } from '@milaboratories/pl-client';\nimport { notEmpty } from '@milaboratories/ts-helpers';\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(\n quickJSError: Error,\n cause: Error,\n ) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = 'PlQuickJSError';\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, '');\n stack = stack.replace(notEmpty(cause.message), '');\n\n this.stack = stack;\n\n const causeMsg = 'fullMessage' in cause && typeof cause.fullMessage === 'string'\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join('\\n\\n');\n const errorFullMessages = errors.map((e) => e.fullMessage).join('\\n\\n');\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = 'PlErrorReport';\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : '';\n const r = this.resource ? resourceIdToString(this.resource) : '';\n const f = this.fieldName ? `/${this.fieldName}` : '';\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : '';\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError =\n | PlInternalError\n | PlTengoError\n | PlRunnerError\n | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(\n public readonly message: string,\n ) {\n super(message);\n this.name = 'PlInternalError';\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = 'PlTengoError';\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = 'PlRunnerError';\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = 'PlMonetizationError';\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z.object({\n errorType: z.string().default(''),\n message: z.string(),\n}).passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: 'initial' as 'initial' | 'path' | 'message',\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split('\\n')) {\n if (state.stage == 'initial') {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = 'path';\n } else if (state.stage == 'path' && line.startsWith('---')) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == 'path' && !isPath(line)) {\n state.stage = 'message';\n } else if (state.stage == 'message' && isPath(line)) {\n state.stage = 'path';\n const text = state.value.join('\\n');\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join('\\n');\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of ['U', 'I', 'O', 'S', 'OTW', 'D', 'MTW']) {\n if (line.startsWith(`[${fieldType}]`))\n return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex = /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex = /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parsed_error.js","sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from \"zod\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport { resourceIdToString, resourceTypeToString } from \"@milaboratories/pl-client\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(quickJSError: Error, cause: Error) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = \"PlQuickJSError\";\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, \"\");\n stack = stack.replace(notEmpty(cause.message), \"\");\n\n this.stack = stack;\n\n const causeMsg =\n \"fullMessage\" in cause && typeof cause.fullMessage === \"string\"\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join(\"\\n\\n\");\n const errorFullMessages = errors.map((e) => e.fullMessage).join(\"\\n\\n\");\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = \"PlErrorReport\";\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : \"\";\n const r = this.resource ? resourceIdToString(this.resource) : \"\";\n const f = this.fieldName ? `/${this.fieldName}` : \"\";\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : \"\";\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(public readonly message: string) {\n super(message);\n this.name = \"PlInternalError\";\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = \"PlTengoError\";\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = \"PlRunnerError\";\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = \"PlMonetizationError\";\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z\n .object({\n errorType: z.string().default(\"\"),\n message: z.string(),\n })\n .passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: \"initial\" as \"initial\" | \"path\" | \"message\",\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split(\"\\n\")) {\n if (state.stage == \"initial\") {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = \"path\";\n } else if (state.stage == \"path\" && line.startsWith(\"---\")) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == \"path\" && !isPath(line)) {\n state.stage = \"message\";\n } else if (state.stage == \"message\" && isPath(line)) {\n state.stage = \"path\";\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of [\"U\", \"I\", \"O\", \"S\", \"OTW\", \"D\", \"MTW\"]) {\n if (line.startsWith(`[${fieldType}]`)) return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex =\n /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex =\n /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-errors",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.59",
|
|
4
4
|
"description": "Parsing errors from Pl backend",
|
|
5
|
-
"
|
|
5
|
+
"files": [
|
|
6
|
+
"./dist/**/*",
|
|
7
|
+
"./src/**/*"
|
|
8
|
+
],
|
|
6
9
|
"main": "./dist/index.cjs",
|
|
7
10
|
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
8
12
|
"exports": {
|
|
9
13
|
".": {
|
|
10
14
|
"types": "./dist/index.d.ts",
|
|
@@ -12,32 +16,29 @@
|
|
|
12
16
|
"import": "./dist/index.js"
|
|
13
17
|
}
|
|
14
18
|
},
|
|
15
|
-
"files": [
|
|
16
|
-
"./dist/**/*",
|
|
17
|
-
"./src/**/*"
|
|
18
|
-
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"zod": "~3.23.8",
|
|
21
|
-
"@milaboratories/
|
|
22
|
-
"@milaboratories/
|
|
21
|
+
"@milaboratories/ts-helpers": "1.7.1",
|
|
22
|
+
"@milaboratories/pl-client": "2.16.27"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
+
"@vitest/coverage-istanbul": "^4.0.16",
|
|
25
26
|
"typescript": "~5.6.3",
|
|
26
27
|
"vitest": "^4.0.16",
|
|
27
|
-
"@
|
|
28
|
-
"
|
|
29
|
-
"@milaboratories/
|
|
30
|
-
"@milaboratories/
|
|
31
|
-
"@milaboratories/ts-builder": "1.2.4",
|
|
32
|
-
"@milaboratories/ts-configs": "1.2.0",
|
|
33
|
-
"@milaboratories/eslint-config": "1.0.5"
|
|
28
|
+
"@milaboratories/pl-error-like": "1.12.6",
|
|
29
|
+
"@milaboratories/build-configs": "1.4.1",
|
|
30
|
+
"@milaboratories/ts-builder": "1.2.5",
|
|
31
|
+
"@milaboratories/ts-configs": "1.2.0"
|
|
34
32
|
},
|
|
35
33
|
"scripts": {
|
|
36
|
-
"type-check": "ts-builder types --target node",
|
|
37
34
|
"build": "ts-builder build --target node",
|
|
38
35
|
"build:watch": "ts-builder build --target node --watch",
|
|
39
|
-
"
|
|
36
|
+
"check": "ts-builder check --target node",
|
|
37
|
+
"formatter:check": "ts-builder formatter --check",
|
|
38
|
+
"linter:check": "ts-builder linter --check",
|
|
39
|
+
"types:check": "ts-builder type-check --target node",
|
|
40
40
|
"test": "vitest run --coverage",
|
|
41
|
-
"do-pack": "rm -f *.tgz && pnpm pack && mv *.tgz package.tgz"
|
|
41
|
+
"do-pack": "rm -f *.tgz && pnpm pack && mv *.tgz package.tgz",
|
|
42
|
+
"fmt": "ts-builder format"
|
|
42
43
|
}
|
|
43
44
|
}
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./parsed_error";
|
package/src/parsed_error.test.ts
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
ResourceId,
|
|
3
|
+
resourceIdFromString,
|
|
4
|
+
stringifyWithResourceId,
|
|
5
|
+
} from "@milaboratories/pl-client";
|
|
6
|
+
import {
|
|
7
|
+
parsePlError,
|
|
8
|
+
parseSubErrors,
|
|
9
|
+
PlMonetizationError,
|
|
10
|
+
PlErrorReport,
|
|
11
|
+
PlRunnerError,
|
|
12
|
+
PlTengoError,
|
|
13
|
+
} from "./parsed_error";
|
|
14
|
+
import { describe, test, it, expect } from "vitest";
|
|
4
15
|
import { ensureErrorLike } from "@milaboratories/pl-error-like";
|
|
5
16
|
|
|
6
|
-
const runnerError =
|
|
17
|
+
const runnerError =
|
|
18
|
+
'{"errorType":"","message":"\\"NG:0x2331A5\\" has 1 input errors:\\n[I] \\"NG:0x2331A5/blob\\": \\"NG:0x2331A4\\" has 1 input errors:\\n[I] \\"NG:0x2331A4/resource\\": \\"NG:0x2331CD\\" has 1 input errors:\\n[I] \\"NG:0x2331CD/resource\\": \\"NG:0x2331CA\\" has 1 input errors:\\n[I] \\"NG:0x2331CA/inputs\\": \\"NG:0x2331CB\\" has 1 input errors:\\n[I] \\"NG:0x2331CB/workdir\\": working directory: \\"workdirs/0x2331E0\\"\\nfailed to run command: \\"java\\" exited with code 22.\\nHere is the latest command output:\\n\\tLicense manager thread died.\\n\\t=== No License ===\\n\\t\\n\\tTo use MiXCR, please, provide a valid license.\\n\\t\\n\\tIf you already have a license, activate it by calling:\\n\\t mixcr activate-license\\n\\t\\n\\t\\n"}';
|
|
7
19
|
|
|
8
|
-
const tengoError =
|
|
20
|
+
const tengoError =
|
|
21
|
+
'{"errorType":"","message":"\\"NG:0x16A\\" has 1 input errors:\\n[I] \\"NG:0x16A/resource\\": cannot eval code: cannot eval template: template: @platforma-open/milaboratories.samples-and-data.workflow:main@1.10.0\\n\\tRuntime Error: File handle not set for \\"R1\\" in sample \\"S63UG7K2IRZSSMAI4UVB5CNJ\\"\\n\\tat @platforma-sdk/workflow-tengo:ll:25:1\\n\\tat @platforma-open/milaboratories.samples-and-data.workflow:main:205:7\\n\\tat @platforma-sdk/workflow-tengo:workflow:264:11\\n\\tat @platforma-sdk/workflow-tengo:tpl:470:11\\n\\tat @platforma-sdk/workflow-tengo:tpl:373:1\\n\\tat @platforma-sdk/workflow-tengo:workflow:261:1\\n\\tat @platforma-open/milaboratories.samples-and-data.workflow:main:35:1"}';
|
|
9
22
|
|
|
10
|
-
const tengoErrorNoErrorType =
|
|
23
|
+
const tengoErrorNoErrorType =
|
|
24
|
+
'{"message":"\\"NG:0x16A\\" has 1 input errors:\\n[I] \\"NG:0x16A/resource\\": cannot eval code: cannot eval template: template: @platforma-open/milaboratories.samples-and-data.workflow:main@1.10.0\\n\\tRuntime Error: File handle not set for \\"R1\\" in sample \\"S63UG7K2IRZSSMAI4UVB5CNJ\\"\\n\\tat @platforma-sdk/workflow-tengo:ll:25:1\\n\\tat @platforma-open/milaboratories.samples-and-data.workflow:main:205:7\\n\\tat @platforma-sdk/workflow-tengo:workflow:264:11\\n\\tat @platforma-sdk/workflow-tengo:tpl:470:11\\n\\tat @platforma-sdk/workflow-tengo:tpl:373:1\\n\\tat @platforma-sdk/workflow-tengo:workflow:261:1\\n\\tat @platforma-open/milaboratories.samples-and-data.workflow:main:35:1"}';
|
|
11
25
|
|
|
12
26
|
const monetizationSubErrors = `"NG:0x1F94C0" has 1 input errors:
|
|
13
27
|
[I] "NG:0x1F94C0/resource": "NG:0x1F94FA" has 1 input errors:
|
|
@@ -33,26 +47,31 @@ Here is the latest command output:
|
|
|
33
47
|
[MTW] "NG:0x1F94E3/workdir": working directory: "workdirs/0x1F9514"
|
|
34
48
|
failed to run command: "/home/snyssfx/PlatformaDev/local/packages/installed/platforma-open/platforma-open/milaboratories.software-small-binaries.mnz-client/main/1.5.9-linux-x64.0x1F1A04/mnz-client" exited with code 1.
|
|
35
49
|
Here is the latest command output:
|
|
36
|
-
2025/03/13 17:25:18 get API error: VALIDATION_ERR Invalid /mnz/run-spec body: field productKey -> Invalid product key
|
|
50
|
+
2025/03/13 17:25:18 get API error: VALIDATION_ERR Invalid /mnz/run-spec body: field productKey -> Invalid product key`;
|
|
37
51
|
|
|
38
|
-
describe(
|
|
39
|
-
it(
|
|
40
|
-
const result = parsePlError(
|
|
52
|
+
describe("parsePlError", () => {
|
|
53
|
+
it("should parse runner error correctly", () => {
|
|
54
|
+
const result = parsePlError(
|
|
55
|
+
runnerError,
|
|
56
|
+
resourceIdFromString("NG:0x2331A5")! as ResourceId,
|
|
57
|
+
{ name: "RunCommand", version: "1" },
|
|
58
|
+
"fieldName",
|
|
59
|
+
);
|
|
41
60
|
|
|
42
61
|
expect(result).toBeInstanceOf(PlErrorReport);
|
|
43
|
-
expect(result.name).toBe(
|
|
44
|
-
expect(result.plErrorType).toBe(
|
|
45
|
-
expect(result.fieldName).toBe(
|
|
46
|
-
expect(stringifyWithResourceId(result.resource)).toBe('
|
|
62
|
+
expect(result.name).toBe("PlErrorReport");
|
|
63
|
+
expect(result.plErrorType).toBe("");
|
|
64
|
+
expect(result.fieldName).toBe("fieldName");
|
|
65
|
+
expect(stringifyWithResourceId(result.resource)).toBe('"NG:0x2331a5"');
|
|
47
66
|
|
|
48
67
|
expect(result.errors.length).toBe(1);
|
|
49
68
|
expect(result.errors[0]).toBeInstanceOf(PlRunnerError);
|
|
50
|
-
expect((result.errors[0] as PlRunnerError).commandName).toBe(
|
|
69
|
+
expect((result.errors[0] as PlRunnerError).commandName).toBe("java");
|
|
51
70
|
expect((result.errors[0] as PlRunnerError).exitCode).toBe(22);
|
|
52
71
|
expect((result.errors[0] as PlRunnerError).stdout).toBeDefined();
|
|
53
|
-
expect((result.errors[0] as PlRunnerError).workingDirectory).toBe(
|
|
72
|
+
expect((result.errors[0] as PlRunnerError).workingDirectory).toBe("workdirs/0x2331E0");
|
|
54
73
|
|
|
55
|
-
expect(
|
|
74
|
+
expect(result.errors[0].message).toBe(`PlRunnerError:
|
|
56
75
|
command: java
|
|
57
76
|
exit code: 22
|
|
58
77
|
working directory: workdirs/0x2331E0
|
|
@@ -66,21 +85,30 @@ License manager thread died.
|
|
|
66
85
|
mixcr activate-license`);
|
|
67
86
|
});
|
|
68
87
|
|
|
69
|
-
it(
|
|
70
|
-
const result = parsePlError(
|
|
88
|
+
it("should parse workflow error correctly", () => {
|
|
89
|
+
const result = parsePlError(
|
|
90
|
+
tengoError,
|
|
91
|
+
resourceIdFromString("NG:0x16A")! as ResourceId,
|
|
92
|
+
{ name: "RunCommand", version: "1" },
|
|
93
|
+
"fieldName",
|
|
94
|
+
);
|
|
71
95
|
|
|
72
96
|
expect(result).toBeInstanceOf(PlErrorReport);
|
|
73
|
-
expect(result.name).toBe(
|
|
74
|
-
expect(result.plErrorType).toBe(
|
|
75
|
-
expect(result.fieldName).toBe(
|
|
76
|
-
expect(stringifyWithResourceId(result.resource)).toBe('
|
|
97
|
+
expect(result.name).toBe("PlErrorReport");
|
|
98
|
+
expect(result.plErrorType).toBe("");
|
|
99
|
+
expect(result.fieldName).toBe("fieldName");
|
|
100
|
+
expect(stringifyWithResourceId(result.resource)).toBe('"NG:0x16a"');
|
|
77
101
|
|
|
78
102
|
expect(result.errors.length).toBe(1);
|
|
79
103
|
expect(result.errors[0]).toBeInstanceOf(PlTengoError);
|
|
80
|
-
expect((result.errors[0] as PlTengoError).templateName).toBe(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
expect((result.errors[0]).
|
|
104
|
+
expect((result.errors[0] as PlTengoError).templateName).toBe(
|
|
105
|
+
"@platforma-open/milaboratories.samples-and-data.workflow:main@1.10.0",
|
|
106
|
+
);
|
|
107
|
+
expect((result.errors[0] as PlTengoError).tengoMessage).toBe(
|
|
108
|
+
'Runtime Error: File handle not set for "R1" in sample "S63UG7K2IRZSSMAI4UVB5CNJ"',
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(result.errors[0].message).toBe(`PlTengoError:
|
|
84
112
|
message:
|
|
85
113
|
Runtime Error: File handle not set for "R1" in sample "S63UG7K2IRZSSMAI4UVB5CNJ"
|
|
86
114
|
template: @platforma-open/milaboratories.samples-and-data.workflow:main@1.10.0
|
|
@@ -95,42 +123,47 @@ at @platforma-sdk/workflow-tengo:ll:25:1
|
|
|
95
123
|
`);
|
|
96
124
|
});
|
|
97
125
|
|
|
98
|
-
it(
|
|
99
|
-
const result = parsePlError(
|
|
126
|
+
it("should parse workflow error correctly even without the error type", () => {
|
|
127
|
+
const result = parsePlError(
|
|
128
|
+
tengoErrorNoErrorType,
|
|
129
|
+
resourceIdFromString("NG:0x16A")! as ResourceId,
|
|
130
|
+
{ name: "RunCommand", version: "1" },
|
|
131
|
+
"fieldName",
|
|
132
|
+
);
|
|
100
133
|
|
|
101
134
|
expect(result).toBeInstanceOf(PlErrorReport);
|
|
102
|
-
expect(result.name).toBe(
|
|
103
|
-
expect(result.plErrorType).toBe(
|
|
135
|
+
expect(result.name).toBe("PlErrorReport");
|
|
136
|
+
expect(result.plErrorType).toBe("");
|
|
104
137
|
|
|
105
138
|
expect(result.errors.length).toBe(1);
|
|
106
139
|
expect(result.errors[0]).toBeInstanceOf(PlTengoError);
|
|
107
140
|
});
|
|
108
141
|
|
|
109
|
-
it(
|
|
142
|
+
it("should parse monetization sub errors correctly", () => {
|
|
110
143
|
const result = parseSubErrors(monetizationSubErrors);
|
|
111
144
|
|
|
112
145
|
expect(result.length).toBe(2);
|
|
113
146
|
|
|
114
147
|
expect(result[0]).toBeInstanceOf(PlMonetizationError);
|
|
115
|
-
expect((result[0] as PlMonetizationError).commandName).toContain(
|
|
148
|
+
expect((result[0] as PlMonetizationError).commandName).toContain("mnz-client");
|
|
116
149
|
expect((result[0] as PlMonetizationError).exitCode).toBe(1);
|
|
117
150
|
expect((result[0] as PlMonetizationError).stdout).toBeDefined();
|
|
118
|
-
expect((result[0] as PlMonetizationError).workingDirectory).toBe(
|
|
151
|
+
expect((result[0] as PlMonetizationError).workingDirectory).toBe("workdirs/0x1F9514");
|
|
119
152
|
|
|
120
153
|
expect(result[1]).toBeInstanceOf(PlMonetizationError);
|
|
121
|
-
expect((result[1] as PlMonetizationError).commandName).toContain(
|
|
154
|
+
expect((result[1] as PlMonetizationError).commandName).toContain("mnz-client");
|
|
122
155
|
expect((result[1] as PlMonetizationError).exitCode).toBe(1);
|
|
123
156
|
expect((result[1] as PlMonetizationError).stdout).toBeDefined();
|
|
124
|
-
expect((result[1] as PlMonetizationError).workingDirectory).toBe(
|
|
157
|
+
expect((result[1] as PlMonetizationError).workingDirectory).toBe("workdirs/0x1F9514");
|
|
125
158
|
|
|
126
|
-
expect(
|
|
159
|
+
expect(result[1].message).toBe(`Monetizaiton error:
|
|
127
160
|
2025/03/13 17:25:18 get API error: VALIDATION_ERR Invalid /mnz/run-spec body: field productKey -> Invalid product key
|
|
128
161
|
`);
|
|
129
162
|
});
|
|
130
163
|
});
|
|
131
164
|
|
|
132
|
-
test(
|
|
133
|
-
const plErrorReport = new PlErrorReport(
|
|
165
|
+
test("pl error report has error like shape", () => {
|
|
166
|
+
const plErrorReport = new PlErrorReport("test error report", "", "", []);
|
|
134
167
|
|
|
135
168
|
const got = ensureErrorLike(plErrorReport);
|
|
136
169
|
|
package/src/parsed_error.ts
CHANGED
|
@@ -1,33 +1,31 @@
|
|
|
1
1
|
/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */
|
|
2
2
|
|
|
3
|
-
import { z } from
|
|
4
|
-
import type { ResourceId, ResourceType } from
|
|
5
|
-
import { resourceIdToString, resourceTypeToString } from
|
|
6
|
-
import { notEmpty } from
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import type { ResourceId, ResourceType } from "@milaboratories/pl-client";
|
|
5
|
+
import { resourceIdToString, resourceTypeToString } from "@milaboratories/pl-client";
|
|
6
|
+
import { notEmpty } from "@milaboratories/ts-helpers";
|
|
7
7
|
|
|
8
8
|
/** The error that comes from QuickJS. */
|
|
9
9
|
export class PlQuickJSError extends Error {
|
|
10
10
|
public stack: string;
|
|
11
11
|
public fullMessage: string;
|
|
12
12
|
|
|
13
|
-
constructor(
|
|
14
|
-
quickJSError: Error,
|
|
15
|
-
cause: Error,
|
|
16
|
-
) {
|
|
13
|
+
constructor(quickJSError: Error, cause: Error) {
|
|
17
14
|
super(`PlQuickJSError: ${cause.message}`, { cause });
|
|
18
|
-
this.name =
|
|
15
|
+
this.name = "PlQuickJSError";
|
|
19
16
|
|
|
20
17
|
// QuickJS wraps the error with the name and the message,
|
|
21
18
|
// but we need another format.
|
|
22
19
|
let stack = notEmpty(quickJSError.stack);
|
|
23
|
-
stack = stack.replace(quickJSError.message,
|
|
24
|
-
stack = stack.replace(notEmpty(cause.message),
|
|
20
|
+
stack = stack.replace(quickJSError.message, "");
|
|
21
|
+
stack = stack.replace(notEmpty(cause.message), "");
|
|
25
22
|
|
|
26
23
|
this.stack = stack;
|
|
27
24
|
|
|
28
|
-
const causeMsg =
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
const causeMsg =
|
|
26
|
+
"fullMessage" in cause && typeof cause.fullMessage === "string"
|
|
27
|
+
? cause.fullMessage
|
|
28
|
+
: cause.message;
|
|
31
29
|
|
|
32
30
|
this.fullMessage = `PlQuickJSError: ${causeMsg}
|
|
33
31
|
QuickJS stacktrace:
|
|
@@ -61,16 +59,16 @@ export class PlErrorReport extends Error {
|
|
|
61
59
|
public readonly resource?: ResourceId,
|
|
62
60
|
public readonly resourceType?: ResourceType,
|
|
63
61
|
) {
|
|
64
|
-
const errorMessages = errors.map((e) => e.message).join(
|
|
65
|
-
const errorFullMessages = errors.map((e) => e.fullMessage).join(
|
|
62
|
+
const errorMessages = errors.map((e) => e.message).join("\n\n");
|
|
63
|
+
const errorFullMessages = errors.map((e) => e.fullMessage).join("\n\n");
|
|
66
64
|
|
|
67
65
|
super(`PlErrorReport: ${errorMessages}`);
|
|
68
|
-
this.name =
|
|
66
|
+
this.name = "PlErrorReport";
|
|
69
67
|
|
|
70
|
-
const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` :
|
|
71
|
-
const r = this.resource ? resourceIdToString(this.resource) :
|
|
72
|
-
const f = this.fieldName ? `/${this.fieldName}` :
|
|
73
|
-
const errType = this.plErrorType ? `error type: ${this.plErrorType}` :
|
|
68
|
+
const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : "";
|
|
69
|
+
const r = this.resource ? resourceIdToString(this.resource) : "";
|
|
70
|
+
const f = this.fieldName ? `/${this.fieldName}` : "";
|
|
71
|
+
const errType = this.plErrorType ? `error type: ${this.plErrorType}` : "";
|
|
74
72
|
|
|
75
73
|
this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
|
|
76
74
|
${errType}
|
|
@@ -82,22 +80,16 @@ ${errorFullMessages}
|
|
|
82
80
|
/**
|
|
83
81
|
* A suberror of a parsed error.
|
|
84
82
|
*/
|
|
85
|
-
export type PlCoreError =
|
|
86
|
-
| PlInternalError
|
|
87
|
-
| PlTengoError
|
|
88
|
-
| PlRunnerError
|
|
89
|
-
| PlMonetizationError;
|
|
83
|
+
export type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;
|
|
90
84
|
|
|
91
85
|
/**
|
|
92
86
|
* An general error when we couldn't parse the cause.
|
|
93
87
|
*/
|
|
94
88
|
export class PlInternalError extends Error {
|
|
95
89
|
public readonly fullMessage: string;
|
|
96
|
-
constructor(
|
|
97
|
-
public readonly message: string,
|
|
98
|
-
) {
|
|
90
|
+
constructor(public readonly message: string) {
|
|
99
91
|
super(message);
|
|
100
|
-
this.name =
|
|
92
|
+
this.name = "PlInternalError";
|
|
101
93
|
this.fullMessage = `PlInternalError: ${message}`;
|
|
102
94
|
}
|
|
103
95
|
}
|
|
@@ -123,7 +115,7 @@ ${tengoStacktrace}
|
|
|
123
115
|
`;
|
|
124
116
|
|
|
125
117
|
super(msg);
|
|
126
|
-
this.name =
|
|
118
|
+
this.name = "PlTengoError";
|
|
127
119
|
|
|
128
120
|
this.fullMessage = `${msg}
|
|
129
121
|
raw message:
|
|
@@ -153,7 +145,7 @@ stdout:
|
|
|
153
145
|
${stdout}`;
|
|
154
146
|
|
|
155
147
|
super(msg);
|
|
156
|
-
this.name =
|
|
148
|
+
this.name = "PlRunnerError";
|
|
157
149
|
this.fullMessage = `
|
|
158
150
|
${msg}
|
|
159
151
|
raw message:
|
|
@@ -180,7 +172,7 @@ ${this.stdout}
|
|
|
180
172
|
`;
|
|
181
173
|
|
|
182
174
|
this.message = msg;
|
|
183
|
-
this.name =
|
|
175
|
+
this.name = "PlMonetizationError";
|
|
184
176
|
|
|
185
177
|
this.fullMessage = `
|
|
186
178
|
${msg}
|
|
@@ -197,10 +189,12 @@ ${this.rawBackendMessage}
|
|
|
197
189
|
/**
|
|
198
190
|
* How the Pl backend represents an error.
|
|
199
191
|
*/
|
|
200
|
-
const backendErrorSchema = z
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
192
|
+
const backendErrorSchema = z
|
|
193
|
+
.object({
|
|
194
|
+
errorType: z.string().default(""),
|
|
195
|
+
message: z.string(),
|
|
196
|
+
})
|
|
197
|
+
.passthrough();
|
|
204
198
|
|
|
205
199
|
/**
|
|
206
200
|
* Parses a Pl error and suberrors from the Pl backend.
|
|
@@ -237,24 +231,24 @@ export function parsePlError(
|
|
|
237
231
|
export function parseSubErrors(message: string): PlCoreError[] {
|
|
238
232
|
// the state of this reducing function
|
|
239
233
|
const state = {
|
|
240
|
-
stage:
|
|
234
|
+
stage: "initial" as "initial" | "path" | "message",
|
|
241
235
|
value: [] as string[],
|
|
242
236
|
result: [] as PlCoreError[],
|
|
243
237
|
};
|
|
244
238
|
|
|
245
|
-
for (const line of message.split(
|
|
246
|
-
if (state.stage ==
|
|
239
|
+
for (const line of message.split("\n")) {
|
|
240
|
+
if (state.stage == "initial") {
|
|
247
241
|
// we need initial stage because apparently the first line
|
|
248
242
|
// of the error doesn't have [I], but is a path line.
|
|
249
|
-
state.stage =
|
|
250
|
-
} else if (state.stage ==
|
|
243
|
+
state.stage = "path";
|
|
244
|
+
} else if (state.stage == "path" && line.startsWith("---")) {
|
|
251
245
|
// we should add stack separator to path stage
|
|
252
246
|
// without break stage processing
|
|
253
|
-
} else if (state.stage ==
|
|
254
|
-
state.stage =
|
|
255
|
-
} else if (state.stage ==
|
|
256
|
-
state.stage =
|
|
257
|
-
const text = state.value.join(
|
|
247
|
+
} else if (state.stage == "path" && !isPath(line)) {
|
|
248
|
+
state.stage = "message";
|
|
249
|
+
} else if (state.stage == "message" && isPath(line)) {
|
|
250
|
+
state.stage = "path";
|
|
251
|
+
const text = state.value.join("\n");
|
|
258
252
|
state.result.push(parseCoreError(text));
|
|
259
253
|
state.value = [];
|
|
260
254
|
}
|
|
@@ -262,16 +256,15 @@ export function parseSubErrors(message: string): PlCoreError[] {
|
|
|
262
256
|
state.value.push(line);
|
|
263
257
|
}
|
|
264
258
|
|
|
265
|
-
const text = state.value.join(
|
|
259
|
+
const text = state.value.join("\n");
|
|
266
260
|
state.result.push(parseCoreError(text));
|
|
267
261
|
|
|
268
262
|
return state.result;
|
|
269
263
|
}
|
|
270
264
|
|
|
271
265
|
function isPath(line: string): boolean {
|
|
272
|
-
for (const fieldType of [
|
|
273
|
-
if (line.startsWith(`[${fieldType}]`))
|
|
274
|
-
return true;
|
|
266
|
+
for (const fieldType of ["U", "I", "O", "S", "OTW", "D", "MTW"]) {
|
|
267
|
+
if (line.startsWith(`[${fieldType}]`)) return true;
|
|
275
268
|
}
|
|
276
269
|
|
|
277
270
|
return false;
|
|
@@ -283,7 +276,8 @@ function isPath(line: string): boolean {
|
|
|
283
276
|
function parseCoreError(message: string): PlCoreError {
|
|
284
277
|
// trying to parse a runner or monetization error.
|
|
285
278
|
// https://regex101.com/r/tmKLj7/1
|
|
286
|
-
const runnerErrorRegex =
|
|
279
|
+
const runnerErrorRegex =
|
|
280
|
+
/working directory: "(.*)"[\s\S]failed to run command: "([^"]+)" exited with code (\d+)\.[\s\S]*?Here is the latest command output:[\s\S]*?\t([\s\S]*)/;
|
|
287
281
|
const match = message.match(runnerErrorRegex);
|
|
288
282
|
if (match) {
|
|
289
283
|
const workingDirectory = match[1];
|
|
@@ -300,7 +294,8 @@ function parseCoreError(message: string): PlCoreError {
|
|
|
300
294
|
|
|
301
295
|
// trying to parse a Tengo error.
|
|
302
296
|
// https://regex101.com/r/1a7RpO/1
|
|
303
|
-
const workflowErrorRegex =
|
|
297
|
+
const workflowErrorRegex =
|
|
298
|
+
/cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/;
|
|
304
299
|
const workflowMatch = message.match(workflowErrorRegex);
|
|
305
300
|
if (workflowMatch) {
|
|
306
301
|
const templateName = workflowMatch[1];
|