@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 CHANGED
@@ -1,2 +1,2 @@
1
- export * from './parsed_error';
1
+ export * from "./parsed_error";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -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 = 'PlQuickJSError';
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 = 'fullMessage' in cause && typeof cause.fullMessage === 'string'
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('\n\n');
55
- const errorFullMessages = errors.map((e) => e.fullMessage).join('\n\n');
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 = '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}` : '';
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 = 'PlInternalError';
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 = 'PlTengoError';
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 = 'PlRunnerError';
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 = 'PlMonetizationError';
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.object({
175
- errorType: zod.z.string().default(''),
174
+ const backendErrorSchema = zod.z
175
+ .object({
176
+ errorType: zod.z.string().default(""),
176
177
  message: zod.z.string(),
177
- }).passthrough();
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: 'initial',
198
+ stage: "initial",
197
199
  value: [],
198
200
  result: [],
199
201
  };
200
- for (const line of message.split('\n')) {
201
- if (state.stage == 'initial') {
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 = 'path';
206
+ state.stage = "path";
205
207
  }
206
- else if (state.stage == 'path' && line.startsWith('---')) ;
207
- else if (state.stage == 'path' && !isPath(line)) {
208
- state.stage = 'message';
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 == 'message' && isPath(line)) {
211
- state.stage = 'path';
212
- const text = state.value.join('\n');
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('\n');
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 ['U', 'I', 'O', 'S', 'OTW', 'D', 'MTW']) {
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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"}
@@ -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 '@milaboratories/pl-client';
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;gBAGzB,YAAY,EAAE,KAAK,EACnB,KAAK,EAAE,KAAK;CAsBf;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,GACnB,eAAe,GACf,YAAY,GACZ,aAAa,GACb,mBAAmB,CAAC;AAExB;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,OAAO,EAAE,MAAM;IAFjC,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAElB,OAAO,EAAE,MAAM;CAMlC;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;AAUD;;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"}
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"}
@@ -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 = 'PlQuickJSError';
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 = 'fullMessage' in cause && typeof cause.fullMessage === 'string'
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('\n\n');
53
- const errorFullMessages = errors.map((e) => e.fullMessage).join('\n\n');
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 = '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}` : '';
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 = 'PlInternalError';
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 = 'PlTengoError';
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 = 'PlRunnerError';
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 = 'PlMonetizationError';
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.object({
173
- errorType: z.string().default(''),
172
+ const backendErrorSchema = z
173
+ .object({
174
+ errorType: z.string().default(""),
174
175
  message: z.string(),
175
- }).passthrough();
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: 'initial',
196
+ stage: "initial",
195
197
  value: [],
196
198
  result: [],
197
199
  };
198
- for (const line of message.split('\n')) {
199
- if (state.stage == 'initial') {
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 = 'path';
204
+ state.stage = "path";
203
205
  }
204
- else if (state.stage == 'path' && line.startsWith('---')) ;
205
- else if (state.stage == 'path' && !isPath(line)) {
206
- state.stage = 'message';
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 == 'message' && isPath(line)) {
209
- state.stage = 'path';
210
- const text = state.value.join('\n');
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('\n');
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 ['U', 'I', 'O', 'S', 'OTW', 'D', 'MTW']) {
223
+ for (const fieldType of ["U", "I", "O", "S", "OTW", "D", "MTW"]) {
222
224
  if (line.startsWith(`[${fieldType}]`))
223
225
  return true;
224
226
  }
@@ -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.58",
3
+ "version": "1.1.59",
4
4
  "description": "Parsing errors from Pl backend",
5
- "types": "./dist/index.d.ts",
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/pl-client": "2.16.26",
22
- "@milaboratories/ts-helpers": "1.7.0"
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
- "@vitest/coverage-istanbul": "^4.0.16",
28
- "eslint": "^9.25.1",
29
- "@milaboratories/pl-error-like": "1.12.5",
30
- "@milaboratories/build-configs": "1.4.0",
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
- "lint": "eslint .",
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 './parsed_error';
1
+ export * from "./parsed_error";
@@ -1,13 +1,27 @@
1
- import { ResourceId, resourceIdFromString, stringifyWithResourceId } from "@milaboratories/pl-client";
2
- import { parsePlError, parseSubErrors, PlMonetizationError, PlErrorReport, PlRunnerError, PlTengoError } from './parsed_error';
3
- import { describe, test, it, expect } from 'vitest';
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 = '{"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"}'
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 = "{\"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\"}"
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 = "{\"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\"}"
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('parsePlError', () => {
39
- it('should parse runner error correctly', () => {
40
- const result = parsePlError(runnerError, resourceIdFromString('NG:0x2331A5')! as ResourceId, { name: 'RunCommand', version: "1" }, 'fieldName',);
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('PlErrorReport');
44
- expect(result.plErrorType).toBe('');
45
- expect(result.fieldName).toBe('fieldName');
46
- expect(stringifyWithResourceId(result.resource)).toBe('\"NG:0x2331a5\"');
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('java');
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('workdirs/0x2331E0');
72
+ expect((result.errors[0] as PlRunnerError).workingDirectory).toBe("workdirs/0x2331E0");
54
73
 
55
- expect((result.errors[0]).message).toBe(`PlRunnerError:
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('should parse workflow error correctly', () => {
70
- const result = parsePlError(tengoError, resourceIdFromString('NG:0x16A')! as ResourceId, { name: 'RunCommand', version: "1" }, 'fieldName');
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('PlErrorReport');
74
- expect(result.plErrorType).toBe('');
75
- expect(result.fieldName).toBe('fieldName');
76
- expect(stringifyWithResourceId(result.resource)).toBe('\"NG:0x16a\"');
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('@platforma-open/milaboratories.samples-and-data.workflow:main@1.10.0');
81
- expect((result.errors[0] as PlTengoError).tengoMessage).toBe('Runtime Error: File handle not set for "R1" in sample "S63UG7K2IRZSSMAI4UVB5CNJ"');
82
-
83
- expect((result.errors[0]).message).toBe(`PlTengoError:
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('should parse workflow error correctly even without the error type', () => {
99
- const result = parsePlError(tengoErrorNoErrorType, resourceIdFromString('NG:0x16A')! as ResourceId, { name: 'RunCommand', version: "1" }, 'fieldName');
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('PlErrorReport');
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('should parse monetization sub errors correctly', () => {
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('mnz-client');
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('workdirs/0x1F9514');
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('mnz-client');
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('workdirs/0x1F9514');
157
+ expect((result[1] as PlMonetizationError).workingDirectory).toBe("workdirs/0x1F9514");
125
158
 
126
- expect((result[1]).message).toBe(`Monetizaiton error:
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('pl error report has error like shape', () => {
133
- const plErrorReport = new PlErrorReport('test error report', '', '', []);
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
 
@@ -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 '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';
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 = 'PlQuickJSError';
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 = 'fullMessage' in cause && typeof cause.fullMessage === 'string'
29
- ? cause.fullMessage
30
- : cause.message;
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('\n\n');
65
- const errorFullMessages = errors.map((e) => e.fullMessage).join('\n\n');
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 = 'PlErrorReport';
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 = 'PlInternalError';
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 = 'PlTengoError';
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 = 'PlRunnerError';
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 = 'PlMonetizationError';
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.object({
201
- errorType: z.string().default(''),
202
- message: z.string(),
203
- }).passthrough();
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: 'initial' as 'initial' | 'path' | 'message',
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('\n')) {
246
- if (state.stage == 'initial') {
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 = 'path';
250
- } else if (state.stage == 'path' && line.startsWith('---')) {
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 == 'path' && !isPath(line)) {
254
- state.stage = 'message';
255
- } else if (state.stage == 'message' && isPath(line)) {
256
- state.stage = 'path';
257
- const text = state.value.join('\n');
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('\n');
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 ['U', 'I', 'O', 'S', 'OTW', 'D', 'MTW']) {
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 = /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]*)/;
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 = /cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/;
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];