@milaboratories/pl-errors 1.0.3 → 1.0.5
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.js +33 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +117 -98
- package/dist/index.mjs.map +1 -1
- package/dist/parsed_error.d.ts +18 -15
- package/dist/parsed_error.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/parsed_error.test.ts +41 -1
- package/src/parsed_error.ts +86 -53
package/dist/index.js
CHANGED
|
@@ -1,33 +1,43 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var z=Object.defineProperty;var v=(t,e,r)=>e in t?z(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var l=(t,e,r)=>v(t,typeof e!="symbol"?e+"":e,r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("zod"),p=require("@milaboratories/pl-client"),m=require("@milaboratories/ts-helpers");class I extends Error{constructor(r,o){super(`PlQuickJSError: ${o.message}`,{cause:o});l(this,"stack");l(this,"fullMessage");this.name="PlQuickJSError";let s=m.notEmpty(r.stack);s=s.replace(r.message,""),s=s.replace(m.notEmpty(o.message),""),this.stack=s;const n="fullMessage"in o&&typeof o.fullMessage=="string"?o.fullMessage:o.message;this.fullMessage=`PlQuickJSError: ${n}
|
|
2
|
+
QuickJS stacktrace:
|
|
3
|
+
${this.stack}
|
|
4
|
+
`}}class E extends Error{constructor(r,o,s,n,a,i,c){const w=n.map(u=>u.message).join(`
|
|
2
5
|
|
|
3
|
-
`)
|
|
4
|
-
|
|
5
|
-
${
|
|
6
|
-
|
|
6
|
+
`),y=n.map(u=>u.fullMessage).join(`
|
|
7
|
+
|
|
8
|
+
`);super(`PlErrorReport: ${w}`);l(this,"fullMessage");this.rawBackendMessage=r,this.plErrorType=o,this.plMessage=s,this.errors=n,this.fieldName=a,this.resource=i,this.resourceType=c,this.name="PlErrorReport";const T=this.resourceType?`${p.resourceTypeToString(this.resourceType)},`:"",S=this.resource?p.resourceIdToString(this.resource):"",x=this.fieldName?`/${this.fieldName}`:"",R=this.plErrorType?`error type: ${this.plErrorType}`:"";this.fullMessage=`PlErrorReport: resource: ${T} ${S}${x}
|
|
9
|
+
${R}
|
|
10
|
+
${y}
|
|
11
|
+
`}}class M extends Error{constructor(r){super(r);l(this,"fullMessage");this.message=r,this.name="PlInternalError",this.fullMessage=`PlInternalError: ${r}`}}class $ extends Error{constructor(r,o,s,n){const a=`PlTengoError:
|
|
7
12
|
message:
|
|
8
|
-
${
|
|
13
|
+
${s}
|
|
14
|
+
template: ${o}
|
|
9
15
|
tengo stacktrace:
|
|
10
|
-
${
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
${this.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
${n}
|
|
17
|
+
`;super(a);l(this,"fullMessage");this.rawBackendMessage=r,this.templateName=o,this.tengoMessage=s,this.tengoStacktrace=n,this.name="PlTengoError",this.fullMessage=`${a}
|
|
18
|
+
raw message:
|
|
19
|
+
${this.rawBackendMessage}
|
|
20
|
+
`}}class h extends Error{constructor(r,o,s,n,a){const i=`PlRunnerError:
|
|
21
|
+
command: ${o}
|
|
22
|
+
exit code: ${s}
|
|
23
|
+
working directory: ${a}
|
|
17
24
|
stdout:
|
|
25
|
+
${n}`;super(i);l(this,"fullMessage");this.rawBackendMessage=r,this.commandName=o,this.exitCode=s,this.stdout=n,this.workingDirectory=a,this.name="PlRunnerError",this.fullMessage=`
|
|
26
|
+
${i}
|
|
27
|
+
raw message:
|
|
28
|
+
${this.rawBackendMessage}
|
|
29
|
+
`}}class P extends h{constructor(r,o,s,n,a){super(r,o,s,n,a);l(this,"fullMessage");const i=`Monetizaiton error:
|
|
18
30
|
${this.stdout}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
${this.fullMessage}`}}class S extends h{constructor(t,o,s,n,i){super(t,o,s,n,i);c(this,"message");this.name="PlMonetizationError",this.message=this.toString()}toString(){return`PlMonetizationError:
|
|
31
|
+
`;this.message=i,this.name="PlMonetizationError",this.fullMessage=`
|
|
32
|
+
${i}
|
|
22
33
|
command: ${this.commandName}
|
|
23
34
|
exit code: ${this.exitCode}
|
|
24
35
|
working directory: ${this.workingDirectory}
|
|
25
|
-
stdout:
|
|
26
|
-
${this.stdout}
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
${this.
|
|
30
|
-
`
|
|
31
|
-
`)
|
|
32
|
-
`);
|
|
37
|
+
raw message:
|
|
38
|
+
${this.rawBackendMessage}
|
|
39
|
+
`}}const b=g.z.object({errorType:g.z.string(),message:g.z.string()});function j(t,e,r,o){const s=b.parse(JSON.parse(t)),n=k(s.message);return new E(t,s.errorType,s.message,n,o,e,r)}function k(t){const e={stage:"initial",value:[],result:[]};for(const o of t.split(`
|
|
40
|
+
`)){if(e.stage=="initial")e.stage="path";else if(e.stage=="path"&&!d(o))e.stage="message";else if(e.stage=="message"&&d(o)){e.stage="path";const s=e.value.join(`
|
|
41
|
+
`);e.result.push(f(s)),e.value=[]}e.value.push(o)}const r=e.value.join(`
|
|
42
|
+
`);return e.result.push(f(r)),e.result}function d(t){for(const e of["U","I","O","S","OTW","D","MTW"])if(t.startsWith(`[${e}]`))return!0;return!1}function f(t){const e=/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]*)/,r=t.match(e);if(r){const n=r[1],a=r[2],i=parseInt(r[3],10),c=r[4].trim();return a.endsWith("mnz-client")&&i==1?new P(t,a,i,c,n):new h(t,a,i,c,n)}const o=/cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/,s=t.match(o);if(s){const n=s[1],a=s[2],i=s[3];return new $(t,n,a,i)}return new M(t)}exports.PlErrorReport=E;exports.PlInternalError=M;exports.PlMonetizationError=P;exports.PlQuickJSError=I;exports.PlRunnerError=h;exports.PlTengoError=$;exports.parsePlError=j;exports.parseSubErrors=k;
|
|
33
43
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.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';\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 message: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly fullMessage: 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 super(fullMessage);\n this.name = 'PlErrorReport';\n this.message = this.toString();\n }\n\n toString() {\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 const subErrors = this.errors.map((e) => e.message).join('\\n\\n');\n\n return `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${subErrors}`;\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 constructor(\n public readonly message: string,\n ) {\n super(message);\n this.name = 'PlInternalError';\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n message: string;\n\n constructor(\n public readonly fullMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n super(fullMessage);\n this.name = 'PlWorkflowError';\n this.message = this.toString();\n }\n\n toString() {\n return `PlWorkflowError:\ntemplate: ${this.templateName}\nmessage:\n${this.tengoMessage}\ntengo stacktrace:\n${this.tengoStacktrace}\n\nfull message:\n${this.fullMessage}`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n message: string;\n\n constructor(\n public readonly fullMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n super(fullMessage);\n this.name = 'PlRunnerError';\n this.message = this.toString();\n }\n\n toString() {\n return `PlRunnerError:\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\nstdout:\n${this.stdout}\n\nfull message:\n${this.fullMessage}`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n message: string;\n\n constructor(\n fullMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(fullMessage, commandName, exitCode, stdout, workingDirectory);\n this.name = 'PlMonetizationError';\n this.message = this.toString();\n }\n\n toString() {\n return `PlMonetizationError:\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\nstdout:\n${this.stdout}\n\nfull message:\n${this.fullMessage}`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z.object({\n errorType: z.string(),\n message: z.string(),\n});\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.parse(JSON.parse(error));\n const subErrors = parseSubErrors(parsed.message);\n\n return new PlErrorReport(\n error,\n parsed.errorType,\n parsed.message,\n subErrors,\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' && !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":["PlErrorReport","fullMessage","plErrorType","plMessage","errors","fieldName","resource","resourceType","__publicField","rt","resourceTypeToString","r","resourceIdToString","f","errType","subErrors","e","PlInternalError","message","PlTengoError","templateName","tengoMessage","tengoStacktrace","PlRunnerError","commandName","exitCode","stdout","workingDirectory","PlMonetizationError","backendErrorSchema","z","parsePlError","error","field","parsed","parseSubErrors","state","line","isPath","text","parseCoreError","fieldType","runnerErrorRegex","match","command","workflowErrorRegex","workflowMatch","errorMessage","stackTrace"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.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(),\n message: z.string(),\n});\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.parse(JSON.parse(error));\n const errors = parseSubErrors(parsed.message);\n\n return new PlErrorReport(\n error,\n parsed.errorType,\n parsed.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' && !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":["PlQuickJSError","quickJSError","cause","__publicField","stack","notEmpty","causeMsg","PlErrorReport","rawBackendMessage","plErrorType","plMessage","errors","fieldName","resource","resourceType","errorMessages","e","errorFullMessages","rt","resourceTypeToString","r","resourceIdToString","f","errType","PlInternalError","message","PlTengoError","templateName","tengoMessage","tengoStacktrace","msg","PlRunnerError","commandName","exitCode","stdout","workingDirectory","PlMonetizationError","backendErrorSchema","z","parsePlError","error","field","parsed","parseSubErrors","state","line","isPath","text","parseCoreError","fieldType","runnerErrorRegex","match","command","workflowErrorRegex","workflowMatch","errorMessage","stackTrace"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,148 +1,167 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var c = (
|
|
4
|
-
import { z as
|
|
5
|
-
import { resourceTypeToString as
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
this
|
|
1
|
+
var P = Object.defineProperty;
|
|
2
|
+
var y = (t, e, r) => e in t ? P(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
|
|
3
|
+
var c = (t, e, r) => y(t, typeof e != "symbol" ? e + "" : e, r);
|
|
4
|
+
import { z as h } from "zod";
|
|
5
|
+
import { resourceTypeToString as T, resourceIdToString as x } from "@milaboratories/pl-client";
|
|
6
|
+
import { notEmpty as g } from "@milaboratories/ts-helpers";
|
|
7
|
+
class W extends Error {
|
|
8
|
+
constructor(r, o) {
|
|
9
|
+
super(`PlQuickJSError: ${o.message}`, { cause: o });
|
|
10
|
+
c(this, "stack");
|
|
11
|
+
c(this, "fullMessage");
|
|
12
|
+
this.name = "PlQuickJSError";
|
|
13
|
+
let s = g(r.stack);
|
|
14
|
+
s = s.replace(r.message, ""), s = s.replace(g(o.message), ""), this.stack = s;
|
|
15
|
+
const n = "fullMessage" in o && typeof o.fullMessage == "string" ? o.fullMessage : o.message;
|
|
16
|
+
this.fullMessage = `PlQuickJSError: ${n}
|
|
17
|
+
QuickJS stacktrace:
|
|
18
|
+
${this.stack}
|
|
19
|
+
`;
|
|
11
20
|
}
|
|
12
|
-
|
|
13
|
-
|
|
21
|
+
}
|
|
22
|
+
class S extends Error {
|
|
23
|
+
constructor(r, o, s, n, a, i, l) {
|
|
24
|
+
const d = n.map((u) => u.message).join(`
|
|
25
|
+
|
|
26
|
+
`), E = n.map((u) => u.fullMessage).join(`
|
|
14
27
|
|
|
15
28
|
`);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
super(`PlErrorReport: ${d}`);
|
|
30
|
+
c(this, "fullMessage");
|
|
31
|
+
this.rawBackendMessage = r, this.plErrorType = o, this.plMessage = s, this.errors = n, this.fieldName = a, this.resource = i, this.resourceType = l, this.name = "PlErrorReport";
|
|
32
|
+
const M = this.resourceType ? `${T(this.resourceType)},` : "", $ = this.resource ? x(this.resource) : "", k = this.fieldName ? `/${this.fieldName}` : "", w = this.plErrorType ? `error type: ${this.plErrorType}` : "";
|
|
33
|
+
this.fullMessage = `PlErrorReport: resource: ${M} ${$}${k}
|
|
34
|
+
${w}
|
|
35
|
+
${E}
|
|
36
|
+
`;
|
|
19
37
|
}
|
|
20
38
|
}
|
|
21
|
-
class
|
|
22
|
-
constructor(
|
|
23
|
-
super(
|
|
39
|
+
class R extends Error {
|
|
40
|
+
constructor(r) {
|
|
41
|
+
super(r);
|
|
42
|
+
c(this, "fullMessage");
|
|
43
|
+
this.message = r, this.name = "PlInternalError", this.fullMessage = `PlInternalError: ${r}`;
|
|
24
44
|
}
|
|
25
45
|
}
|
|
26
|
-
class
|
|
46
|
+
class v extends Error {
|
|
27
47
|
constructor(r, o, s, n) {
|
|
28
|
-
|
|
29
|
-
c(this, "message");
|
|
30
|
-
this.fullMessage = r, this.templateName = o, this.tengoMessage = s, this.tengoStacktrace = n, this.name = "PlWorkflowError", this.message = this.toString();
|
|
31
|
-
}
|
|
32
|
-
toString() {
|
|
33
|
-
return `PlWorkflowError:
|
|
34
|
-
template: ${this.templateName}
|
|
48
|
+
const a = `PlTengoError:
|
|
35
49
|
message:
|
|
36
|
-
${
|
|
50
|
+
${s}
|
|
51
|
+
template: ${o}
|
|
37
52
|
tengo stacktrace:
|
|
38
|
-
${
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
53
|
+
${n}
|
|
54
|
+
`;
|
|
55
|
+
super(a);
|
|
56
|
+
c(this, "fullMessage");
|
|
57
|
+
this.rawBackendMessage = r, this.templateName = o, this.tengoMessage = s, this.tengoStacktrace = n, this.name = "PlTengoError", this.fullMessage = `${a}
|
|
58
|
+
raw message:
|
|
59
|
+
${this.rawBackendMessage}
|
|
60
|
+
`;
|
|
42
61
|
}
|
|
43
62
|
}
|
|
44
|
-
class
|
|
45
|
-
constructor(r, o, s, n,
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
toString() {
|
|
51
|
-
return `PlRunnerError:
|
|
52
|
-
command: ${this.commandName}
|
|
53
|
-
exit code: ${this.exitCode}
|
|
54
|
-
working directory: ${this.workingDirectory}
|
|
63
|
+
class f extends Error {
|
|
64
|
+
constructor(r, o, s, n, a) {
|
|
65
|
+
const i = `PlRunnerError:
|
|
66
|
+
command: ${o}
|
|
67
|
+
exit code: ${s}
|
|
68
|
+
working directory: ${a}
|
|
55
69
|
stdout:
|
|
56
|
-
${
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
${n}`;
|
|
71
|
+
super(i);
|
|
72
|
+
c(this, "fullMessage");
|
|
73
|
+
this.rawBackendMessage = r, this.commandName = o, this.exitCode = s, this.stdout = n, this.workingDirectory = a, this.name = "PlRunnerError", this.fullMessage = `
|
|
74
|
+
${i}
|
|
75
|
+
raw message:
|
|
76
|
+
${this.rawBackendMessage}
|
|
77
|
+
`;
|
|
60
78
|
}
|
|
61
79
|
}
|
|
62
|
-
class
|
|
63
|
-
constructor(r, o, s, n,
|
|
64
|
-
super(r, o, s, n,
|
|
65
|
-
c(this, "
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
class B extends f {
|
|
81
|
+
constructor(r, o, s, n, a) {
|
|
82
|
+
super(r, o, s, n, a);
|
|
83
|
+
c(this, "fullMessage");
|
|
84
|
+
const i = `Monetizaiton error:
|
|
85
|
+
${this.stdout}
|
|
86
|
+
`;
|
|
87
|
+
this.message = i, this.name = "PlMonetizationError", this.fullMessage = `
|
|
88
|
+
${i}
|
|
70
89
|
command: ${this.commandName}
|
|
71
90
|
exit code: ${this.exitCode}
|
|
72
91
|
working directory: ${this.workingDirectory}
|
|
73
|
-
stdout:
|
|
74
|
-
${this.stdout}
|
|
75
92
|
|
|
76
|
-
|
|
77
|
-
${this.
|
|
93
|
+
raw message:
|
|
94
|
+
${this.rawBackendMessage}
|
|
95
|
+
`;
|
|
78
96
|
}
|
|
79
97
|
}
|
|
80
|
-
const
|
|
81
|
-
errorType:
|
|
82
|
-
message:
|
|
98
|
+
const I = h.object({
|
|
99
|
+
errorType: h.string(),
|
|
100
|
+
message: h.string()
|
|
83
101
|
});
|
|
84
|
-
function
|
|
85
|
-
const s =
|
|
86
|
-
return new
|
|
87
|
-
|
|
102
|
+
function b(t, e, r, o) {
|
|
103
|
+
const s = I.parse(JSON.parse(t)), n = N(s.message);
|
|
104
|
+
return new S(
|
|
105
|
+
t,
|
|
88
106
|
s.errorType,
|
|
89
107
|
s.message,
|
|
90
108
|
n,
|
|
91
109
|
o,
|
|
92
|
-
|
|
110
|
+
e,
|
|
93
111
|
r
|
|
94
112
|
);
|
|
95
113
|
}
|
|
96
|
-
function
|
|
97
|
-
const
|
|
114
|
+
function N(t) {
|
|
115
|
+
const e = {
|
|
98
116
|
stage: "initial",
|
|
99
117
|
value: [],
|
|
100
118
|
result: []
|
|
101
119
|
};
|
|
102
|
-
for (const o of
|
|
120
|
+
for (const o of t.split(`
|
|
103
121
|
`)) {
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
else if (
|
|
107
|
-
|
|
108
|
-
else if (
|
|
109
|
-
|
|
110
|
-
const s =
|
|
122
|
+
if (e.stage == "initial")
|
|
123
|
+
e.stage = "path";
|
|
124
|
+
else if (e.stage == "path" && !p(o))
|
|
125
|
+
e.stage = "message";
|
|
126
|
+
else if (e.stage == "message" && p(o)) {
|
|
127
|
+
e.stage = "path";
|
|
128
|
+
const s = e.value.join(`
|
|
111
129
|
`);
|
|
112
|
-
|
|
130
|
+
e.result.push(m(s)), e.value = [];
|
|
113
131
|
}
|
|
114
|
-
|
|
132
|
+
e.value.push(o);
|
|
115
133
|
}
|
|
116
|
-
const r =
|
|
134
|
+
const r = e.value.join(`
|
|
117
135
|
`);
|
|
118
|
-
return
|
|
136
|
+
return e.result.push(m(r)), e.result;
|
|
119
137
|
}
|
|
120
|
-
function
|
|
121
|
-
for (const
|
|
122
|
-
if (
|
|
138
|
+
function p(t) {
|
|
139
|
+
for (const e of ["U", "I", "O", "S", "OTW", "D", "MTW"])
|
|
140
|
+
if (t.startsWith(`[${e}]`))
|
|
123
141
|
return !0;
|
|
124
142
|
return !1;
|
|
125
143
|
}
|
|
126
|
-
function m(
|
|
127
|
-
const
|
|
144
|
+
function m(t) {
|
|
145
|
+
const e = /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]*)/, r = t.match(e);
|
|
128
146
|
if (r) {
|
|
129
|
-
const n = r[1],
|
|
130
|
-
return
|
|
147
|
+
const n = r[1], a = r[2], i = parseInt(r[3], 10), l = r[4].trim();
|
|
148
|
+
return a.endsWith("mnz-client") && i == 1 ? new B(t, a, i, l, n) : new f(t, a, i, l, n);
|
|
131
149
|
}
|
|
132
|
-
const o = /cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/, s =
|
|
150
|
+
const o = /cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/, s = t.match(o);
|
|
133
151
|
if (s) {
|
|
134
|
-
const n = s[1],
|
|
135
|
-
return new
|
|
152
|
+
const n = s[1], a = s[2], i = s[3];
|
|
153
|
+
return new v(t, n, a, i);
|
|
136
154
|
}
|
|
137
|
-
return new
|
|
155
|
+
return new R(t);
|
|
138
156
|
}
|
|
139
157
|
export {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
158
|
+
S as PlErrorReport,
|
|
159
|
+
R as PlInternalError,
|
|
160
|
+
B as PlMonetizationError,
|
|
161
|
+
W as PlQuickJSError,
|
|
162
|
+
f as PlRunnerError,
|
|
163
|
+
v as PlTengoError,
|
|
164
|
+
b as parsePlError,
|
|
165
|
+
N as parseSubErrors
|
|
147
166
|
};
|
|
148
167
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","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';\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 message: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly fullMessage: 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 super(fullMessage);\n this.name = 'PlErrorReport';\n this.message = this.toString();\n }\n\n toString() {\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 const subErrors = this.errors.map((e) => e.message).join('\\n\\n');\n\n return `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${subErrors}`;\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 constructor(\n public readonly message: string,\n ) {\n super(message);\n this.name = 'PlInternalError';\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n message: string;\n\n constructor(\n public readonly fullMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n super(fullMessage);\n this.name = 'PlWorkflowError';\n this.message = this.toString();\n }\n\n toString() {\n return `PlWorkflowError:\ntemplate: ${this.templateName}\nmessage:\n${this.tengoMessage}\ntengo stacktrace:\n${this.tengoStacktrace}\n\nfull message:\n${this.fullMessage}`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n message: string;\n\n constructor(\n public readonly fullMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n super(fullMessage);\n this.name = 'PlRunnerError';\n this.message = this.toString();\n }\n\n toString() {\n return `PlRunnerError:\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\nstdout:\n${this.stdout}\n\nfull message:\n${this.fullMessage}`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n message: string;\n\n constructor(\n fullMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(fullMessage, commandName, exitCode, stdout, workingDirectory);\n this.name = 'PlMonetizationError';\n this.message = this.toString();\n }\n\n toString() {\n return `PlMonetizationError:\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\nstdout:\n${this.stdout}\n\nfull message:\n${this.fullMessage}`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z.object({\n errorType: z.string(),\n message: z.string(),\n});\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.parse(JSON.parse(error));\n const subErrors = parseSubErrors(parsed.message);\n\n return new PlErrorReport(\n error,\n parsed.errorType,\n parsed.message,\n subErrors,\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' && !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":["PlErrorReport","fullMessage","plErrorType","plMessage","errors","fieldName","resource","resourceType","__publicField","rt","resourceTypeToString","r","resourceIdToString","f","errType","subErrors","e","PlInternalError","message","PlTengoError","templateName","tengoMessage","tengoStacktrace","PlRunnerError","commandName","exitCode","stdout","workingDirectory","PlMonetizationError","backendErrorSchema","z","parsePlError","error","field","parsed","parseSubErrors","state","line","isPath","text","parseCoreError","fieldType","runnerErrorRegex","match","command","workflowErrorRegex","workflowMatch","errorMessage","stackTrace"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","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(),\n message: z.string(),\n});\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.parse(JSON.parse(error));\n const errors = parseSubErrors(parsed.message);\n\n return new PlErrorReport(\n error,\n parsed.errorType,\n parsed.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' && !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":["PlQuickJSError","quickJSError","cause","__publicField","stack","notEmpty","causeMsg","PlErrorReport","rawBackendMessage","plErrorType","plMessage","errors","fieldName","resource","resourceType","errorMessages","e","errorFullMessages","rt","resourceTypeToString","r","resourceIdToString","f","errType","PlInternalError","message","PlTengoError","templateName","tengoMessage","tengoStacktrace","msg","PlRunnerError","commandName","exitCode","stdout","workingDirectory","PlMonetizationError","backendErrorSchema","z","parsePlError","error","field","parsed","parseSubErrors","state","line","isPath","text","parseCoreError","fieldType","runnerErrorRegex","match","command","workflowErrorRegex","workflowMatch","errorMessage","stackTrace"],"mappings":"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"}
|
package/dist/parsed_error.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { ResourceId, ResourceType } from '@milaboratories/pl-client';
|
|
2
|
+
/** The error that comes from QuickJS. */
|
|
3
|
+
export declare class PlQuickJSError extends Error {
|
|
4
|
+
stack: string;
|
|
5
|
+
fullMessage: string;
|
|
6
|
+
constructor(quickJSError: Error, cause: Error);
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
9
|
* A parsed error from the Pl backend.
|
|
4
10
|
* It contains several suberrors, which could be one or different causes of the error.
|
|
5
11
|
*/
|
|
6
12
|
export declare class PlErrorReport extends Error {
|
|
7
13
|
/** Full message from the Pl backend. */
|
|
8
|
-
readonly
|
|
14
|
+
readonly rawBackendMessage: string;
|
|
9
15
|
/** Either CID conflict or a error from controller. */
|
|
10
16
|
readonly plErrorType: string;
|
|
11
17
|
/** Parsed pl backend message that will be futher parsed into suberrors. */
|
|
@@ -16,10 +22,10 @@ export declare class PlErrorReport extends Error {
|
|
|
16
22
|
readonly fieldName?: string | undefined;
|
|
17
23
|
readonly resource?: ResourceId | undefined;
|
|
18
24
|
readonly resourceType?: ResourceType | undefined;
|
|
19
|
-
|
|
25
|
+
readonly fullMessage: string;
|
|
20
26
|
constructor(
|
|
21
27
|
/** Full message from the Pl backend. */
|
|
22
|
-
|
|
28
|
+
rawBackendMessage: string,
|
|
23
29
|
/** Either CID conflict or a error from controller. */
|
|
24
30
|
plErrorType: string,
|
|
25
31
|
/** Parsed pl backend message that will be futher parsed into suberrors. */
|
|
@@ -28,7 +34,6 @@ export declare class PlErrorReport extends Error {
|
|
|
28
34
|
errors: PlCoreError[],
|
|
29
35
|
/** Optional info about a resource where the error happened. */
|
|
30
36
|
fieldName?: string | undefined, resource?: ResourceId | undefined, resourceType?: ResourceType | undefined);
|
|
31
|
-
toString(): string;
|
|
32
37
|
}
|
|
33
38
|
/**
|
|
34
39
|
* A suberror of a parsed error.
|
|
@@ -39,40 +44,38 @@ export type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMon
|
|
|
39
44
|
*/
|
|
40
45
|
export declare class PlInternalError extends Error {
|
|
41
46
|
readonly message: string;
|
|
47
|
+
readonly fullMessage: string;
|
|
42
48
|
constructor(message: string);
|
|
43
49
|
}
|
|
44
50
|
/**
|
|
45
51
|
* Happens when workflow template panics.
|
|
46
52
|
*/
|
|
47
53
|
export declare class PlTengoError extends Error {
|
|
48
|
-
readonly
|
|
54
|
+
readonly rawBackendMessage: string;
|
|
49
55
|
readonly templateName: string;
|
|
50
56
|
readonly tengoMessage: string;
|
|
51
57
|
readonly tengoStacktrace: string;
|
|
52
|
-
|
|
53
|
-
constructor(
|
|
54
|
-
toString(): string;
|
|
58
|
+
readonly fullMessage: string;
|
|
59
|
+
constructor(rawBackendMessage: string, templateName: string, tengoMessage: string, tengoStacktrace: string);
|
|
55
60
|
}
|
|
56
61
|
/**
|
|
57
62
|
* Happens when a command fails to run.
|
|
58
63
|
*/
|
|
59
64
|
export declare class PlRunnerError extends Error {
|
|
60
|
-
readonly
|
|
65
|
+
readonly rawBackendMessage: string;
|
|
61
66
|
readonly commandName: string;
|
|
62
67
|
readonly exitCode: number;
|
|
63
68
|
readonly stdout: string;
|
|
64
69
|
readonly workingDirectory: string;
|
|
65
|
-
|
|
66
|
-
constructor(
|
|
67
|
-
toString(): string;
|
|
70
|
+
readonly fullMessage: string;
|
|
71
|
+
constructor(rawBackendMessage: string, commandName: string, exitCode: number, stdout: string, workingDirectory: string);
|
|
68
72
|
}
|
|
69
73
|
/**
|
|
70
74
|
* Happens when a monetization command fails to run.
|
|
71
75
|
*/
|
|
72
76
|
export declare class PlMonetizationError extends PlRunnerError {
|
|
73
|
-
|
|
74
|
-
constructor(
|
|
75
|
-
toString(): string;
|
|
77
|
+
readonly fullMessage: string;
|
|
78
|
+
constructor(rawBackendMessage: string, commandName: string, exitCode: number, stdout: string, workingDirectory: string);
|
|
76
79
|
}
|
|
77
80
|
/**
|
|
78
81
|
* Parses a Pl error and suberrors from the Pl backend.
|
|
@@ -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;
|
|
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,CAcf;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CA6B7D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-errors",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Parsing errors from Pl backend",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,12 +18,14 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"zod": "~3.23.8",
|
|
21
|
-
"@milaboratories/
|
|
21
|
+
"@milaboratories/ts-helpers": "1.1.5",
|
|
22
|
+
"@milaboratories/pl-client": "2.8.0"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"typescript": "~5.5.4",
|
|
25
26
|
"vite": "^5.4.11",
|
|
26
27
|
"vitest": "^2.1.8",
|
|
28
|
+
"@milaboratories/pl-error-like": "1.12.0",
|
|
27
29
|
"@milaboratories/platforma-build-configs": "1.0.3",
|
|
28
30
|
"@milaboratories/eslint-config": "^1.0.4"
|
|
29
31
|
},
|
package/src/parsed_error.test.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ResourceId, resourceIdFromString, stringifyWithResourceId } from "@milaboratories/pl-client";
|
|
2
2
|
import { parsePlError, parseSubErrors, PlMonetizationError, PlErrorReport, PlRunnerError, PlTengoError } from './parsed_error';
|
|
3
|
-
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import { describe, test, it, expect } from 'vitest';
|
|
4
|
+
import { ensureErrorLike } from "@milaboratories/pl-error-like";
|
|
4
5
|
|
|
5
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"}'
|
|
6
7
|
|
|
@@ -47,6 +48,19 @@ describe('parsePlError', () => {
|
|
|
47
48
|
expect((result.errors[0] as PlRunnerError).exitCode).toBe(22);
|
|
48
49
|
expect((result.errors[0] as PlRunnerError).stdout).toBeDefined();
|
|
49
50
|
expect((result.errors[0] as PlRunnerError).workingDirectory).toBe('workdirs/0x2331E0');
|
|
51
|
+
|
|
52
|
+
expect((result.errors[0]).message).toBe(`PlRunnerError:
|
|
53
|
+
command: java
|
|
54
|
+
exit code: 22
|
|
55
|
+
working directory: workdirs/0x2331E0
|
|
56
|
+
stdout:
|
|
57
|
+
License manager thread died.
|
|
58
|
+
=== No License ===
|
|
59
|
+
|
|
60
|
+
To use MiXCR, please, provide a valid license.
|
|
61
|
+
|
|
62
|
+
If you already have a license, activate it by calling:
|
|
63
|
+
mixcr activate-license`);
|
|
50
64
|
});
|
|
51
65
|
|
|
52
66
|
it('should parse workflow error correctly', () => {
|
|
@@ -62,6 +76,20 @@ describe('parsePlError', () => {
|
|
|
62
76
|
expect(result.errors[0]).toBeInstanceOf(PlTengoError);
|
|
63
77
|
expect((result.errors[0] as PlTengoError).templateName).toBe('@platforma-open/milaboratories.samples-and-data.workflow:main@1.10.0');
|
|
64
78
|
expect((result.errors[0] as PlTengoError).tengoMessage).toBe('Runtime Error: File handle not set for "R1" in sample "S63UG7K2IRZSSMAI4UVB5CNJ"');
|
|
79
|
+
|
|
80
|
+
expect((result.errors[0]).message).toBe(`PlTengoError:
|
|
81
|
+
message:
|
|
82
|
+
Runtime Error: File handle not set for "R1" in sample "S63UG7K2IRZSSMAI4UVB5CNJ"
|
|
83
|
+
template: @platforma-open/milaboratories.samples-and-data.workflow:main@1.10.0
|
|
84
|
+
tengo stacktrace:
|
|
85
|
+
at @platforma-sdk/workflow-tengo:ll:25:1
|
|
86
|
+
at @platforma-open/milaboratories.samples-and-data.workflow:main:205:7
|
|
87
|
+
at @platforma-sdk/workflow-tengo:workflow:264:11
|
|
88
|
+
at @platforma-sdk/workflow-tengo:tpl:470:11
|
|
89
|
+
at @platforma-sdk/workflow-tengo:tpl:373:1
|
|
90
|
+
at @platforma-sdk/workflow-tengo:workflow:261:1
|
|
91
|
+
at @platforma-open/milaboratories.samples-and-data.workflow:main:35:1
|
|
92
|
+
`);
|
|
65
93
|
});
|
|
66
94
|
|
|
67
95
|
it('should parse monetization sub errors correctly', () => {
|
|
@@ -80,5 +108,17 @@ describe('parsePlError', () => {
|
|
|
80
108
|
expect((result[1] as PlMonetizationError).exitCode).toBe(1);
|
|
81
109
|
expect((result[1] as PlMonetizationError).stdout).toBeDefined();
|
|
82
110
|
expect((result[1] as PlMonetizationError).workingDirectory).toBe('workdirs/0x1F9514');
|
|
111
|
+
|
|
112
|
+
expect((result[1]).message).toBe(`Monetizaiton error:
|
|
113
|
+
2025/03/13 17:25:18 get API error: VALIDATION_ERR Invalid /mnz/run-spec body: field productKey -> Invalid product key
|
|
114
|
+
`);
|
|
83
115
|
});
|
|
84
116
|
});
|
|
117
|
+
|
|
118
|
+
test('pl error report has error like shape', () => {
|
|
119
|
+
const plErrorReport = new PlErrorReport('test error report', '', '', []);
|
|
120
|
+
|
|
121
|
+
const got = ensureErrorLike(plErrorReport);
|
|
122
|
+
|
|
123
|
+
expect(got).toBeDefined();
|
|
124
|
+
});
|
package/src/parsed_error.ts
CHANGED
|
@@ -3,17 +3,49 @@
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import type { ResourceId, ResourceType } from '@milaboratories/pl-client';
|
|
5
5
|
import { resourceIdToString, resourceTypeToString } from '@milaboratories/pl-client';
|
|
6
|
+
import { notEmpty } from '@milaboratories/ts-helpers';
|
|
7
|
+
|
|
8
|
+
/** The error that comes from QuickJS. */
|
|
9
|
+
export class PlQuickJSError extends Error {
|
|
10
|
+
public stack: string;
|
|
11
|
+
public fullMessage: string;
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
quickJSError: Error,
|
|
15
|
+
cause: Error,
|
|
16
|
+
) {
|
|
17
|
+
super(`PlQuickJSError: ${cause.message}`, { cause });
|
|
18
|
+
this.name = 'PlQuickJSError';
|
|
19
|
+
|
|
20
|
+
// QuickJS wraps the error with the name and the message,
|
|
21
|
+
// but we need another format.
|
|
22
|
+
let stack = notEmpty(quickJSError.stack);
|
|
23
|
+
stack = stack.replace(quickJSError.message, '');
|
|
24
|
+
stack = stack.replace(notEmpty(cause.message), '');
|
|
25
|
+
|
|
26
|
+
this.stack = stack;
|
|
27
|
+
|
|
28
|
+
const causeMsg = 'fullMessage' in cause && typeof cause.fullMessage === 'string'
|
|
29
|
+
? cause.fullMessage
|
|
30
|
+
: cause.message;
|
|
31
|
+
|
|
32
|
+
this.fullMessage = `PlQuickJSError: ${causeMsg}
|
|
33
|
+
QuickJS stacktrace:
|
|
34
|
+
${this.stack}
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
6
38
|
|
|
7
39
|
/**
|
|
8
40
|
* A parsed error from the Pl backend.
|
|
9
41
|
* It contains several suberrors, which could be one or different causes of the error.
|
|
10
42
|
*/
|
|
11
43
|
export class PlErrorReport extends Error {
|
|
12
|
-
|
|
44
|
+
public readonly fullMessage: string;
|
|
13
45
|
|
|
14
46
|
constructor(
|
|
15
47
|
/** Full message from the Pl backend. */
|
|
16
|
-
public readonly
|
|
48
|
+
public readonly rawBackendMessage: string,
|
|
17
49
|
|
|
18
50
|
/** Either CID conflict or a error from controller. */
|
|
19
51
|
public readonly plErrorType: string,
|
|
@@ -29,21 +61,21 @@ export class PlErrorReport extends Error {
|
|
|
29
61
|
public readonly resource?: ResourceId,
|
|
30
62
|
public readonly resourceType?: ResourceType,
|
|
31
63
|
) {
|
|
32
|
-
|
|
64
|
+
const errorMessages = errors.map((e) => e.message).join('\n\n');
|
|
65
|
+
const errorFullMessages = errors.map((e) => e.fullMessage).join('\n\n');
|
|
66
|
+
|
|
67
|
+
super(`PlErrorReport: ${errorMessages}`);
|
|
33
68
|
this.name = 'PlErrorReport';
|
|
34
|
-
this.message = this.toString();
|
|
35
|
-
}
|
|
36
69
|
|
|
37
|
-
toString() {
|
|
38
70
|
const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : '';
|
|
39
71
|
const r = this.resource ? resourceIdToString(this.resource) : '';
|
|
40
72
|
const f = this.fieldName ? `/${this.fieldName}` : '';
|
|
41
73
|
const errType = this.plErrorType ? `error type: ${this.plErrorType}` : '';
|
|
42
|
-
const subErrors = this.errors.map((e) => e.message).join('\n\n');
|
|
43
74
|
|
|
44
|
-
|
|
75
|
+
this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
|
|
45
76
|
${errType}
|
|
46
|
-
${
|
|
77
|
+
${errorFullMessages}
|
|
78
|
+
`;
|
|
47
79
|
}
|
|
48
80
|
}
|
|
49
81
|
|
|
@@ -60,11 +92,13 @@ export type PlCoreError =
|
|
|
60
92
|
* An general error when we couldn't parse the cause.
|
|
61
93
|
*/
|
|
62
94
|
export class PlInternalError extends Error {
|
|
95
|
+
public readonly fullMessage: string;
|
|
63
96
|
constructor(
|
|
64
97
|
public readonly message: string,
|
|
65
98
|
) {
|
|
66
99
|
super(message);
|
|
67
100
|
this.name = 'PlInternalError';
|
|
101
|
+
this.fullMessage = `PlInternalError: ${message}`;
|
|
68
102
|
}
|
|
69
103
|
}
|
|
70
104
|
|
|
@@ -72,29 +106,29 @@ export class PlInternalError extends Error {
|
|
|
72
106
|
* Happens when workflow template panics.
|
|
73
107
|
*/
|
|
74
108
|
export class PlTengoError extends Error {
|
|
75
|
-
|
|
109
|
+
public readonly fullMessage: string;
|
|
76
110
|
|
|
77
111
|
constructor(
|
|
78
|
-
public readonly
|
|
112
|
+
public readonly rawBackendMessage: string,
|
|
79
113
|
public readonly templateName: string,
|
|
80
114
|
public readonly tengoMessage: string,
|
|
81
115
|
public readonly tengoStacktrace: string,
|
|
82
116
|
) {
|
|
83
|
-
|
|
84
|
-
this.name = 'PlWorkflowError';
|
|
85
|
-
this.message = this.toString();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
toString() {
|
|
89
|
-
return `PlWorkflowError:
|
|
90
|
-
template: ${this.templateName}
|
|
117
|
+
const msg = `PlTengoError:
|
|
91
118
|
message:
|
|
92
|
-
${
|
|
119
|
+
${tengoMessage}
|
|
120
|
+
template: ${templateName}
|
|
93
121
|
tengo stacktrace:
|
|
94
|
-
${
|
|
122
|
+
${tengoStacktrace}
|
|
123
|
+
`;
|
|
124
|
+
|
|
125
|
+
super(msg);
|
|
126
|
+
this.name = 'PlTengoError';
|
|
95
127
|
|
|
96
|
-
|
|
97
|
-
|
|
128
|
+
this.fullMessage = `${msg}
|
|
129
|
+
raw message:
|
|
130
|
+
${this.rawBackendMessage}
|
|
131
|
+
`;
|
|
98
132
|
}
|
|
99
133
|
}
|
|
100
134
|
|
|
@@ -102,30 +136,29 @@ ${this.fullMessage}`;
|
|
|
102
136
|
* Happens when a command fails to run.
|
|
103
137
|
*/
|
|
104
138
|
export class PlRunnerError extends Error {
|
|
105
|
-
|
|
139
|
+
public readonly fullMessage: string;
|
|
106
140
|
|
|
107
141
|
constructor(
|
|
108
|
-
public readonly
|
|
142
|
+
public readonly rawBackendMessage: string,
|
|
109
143
|
public readonly commandName: string,
|
|
110
144
|
public readonly exitCode: number,
|
|
111
145
|
public readonly stdout: string,
|
|
112
146
|
public readonly workingDirectory: string,
|
|
113
147
|
) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
toString() {
|
|
120
|
-
return `PlRunnerError:
|
|
121
|
-
command: ${this.commandName}
|
|
122
|
-
exit code: ${this.exitCode}
|
|
123
|
-
working directory: ${this.workingDirectory}
|
|
148
|
+
const msg = `PlRunnerError:
|
|
149
|
+
command: ${commandName}
|
|
150
|
+
exit code: ${exitCode}
|
|
151
|
+
working directory: ${workingDirectory}
|
|
124
152
|
stdout:
|
|
125
|
-
${
|
|
153
|
+
${stdout}`;
|
|
126
154
|
|
|
127
|
-
|
|
128
|
-
|
|
155
|
+
super(msg);
|
|
156
|
+
this.name = 'PlRunnerError';
|
|
157
|
+
this.fullMessage = `
|
|
158
|
+
${msg}
|
|
159
|
+
raw message:
|
|
160
|
+
${this.rawBackendMessage}
|
|
161
|
+
`;
|
|
129
162
|
}
|
|
130
163
|
}
|
|
131
164
|
|
|
@@ -133,30 +166,31 @@ ${this.fullMessage}`;
|
|
|
133
166
|
* Happens when a monetization command fails to run.
|
|
134
167
|
*/
|
|
135
168
|
export class PlMonetizationError extends PlRunnerError {
|
|
136
|
-
|
|
137
|
-
|
|
169
|
+
public readonly fullMessage: string;
|
|
138
170
|
constructor(
|
|
139
|
-
|
|
171
|
+
rawBackendMessage: string,
|
|
140
172
|
commandName: string,
|
|
141
173
|
exitCode: number,
|
|
142
174
|
stdout: string,
|
|
143
175
|
workingDirectory: string,
|
|
144
176
|
) {
|
|
145
|
-
super(
|
|
177
|
+
super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);
|
|
178
|
+
const msg = `Monetizaiton error:
|
|
179
|
+
${this.stdout}
|
|
180
|
+
`;
|
|
181
|
+
|
|
182
|
+
this.message = msg;
|
|
146
183
|
this.name = 'PlMonetizationError';
|
|
147
|
-
this.message = this.toString();
|
|
148
|
-
}
|
|
149
184
|
|
|
150
|
-
|
|
151
|
-
|
|
185
|
+
this.fullMessage = `
|
|
186
|
+
${msg}
|
|
152
187
|
command: ${this.commandName}
|
|
153
188
|
exit code: ${this.exitCode}
|
|
154
189
|
working directory: ${this.workingDirectory}
|
|
155
|
-
stdout:
|
|
156
|
-
${this.stdout}
|
|
157
190
|
|
|
158
|
-
|
|
159
|
-
${this.
|
|
191
|
+
raw message:
|
|
192
|
+
${this.rawBackendMessage}
|
|
193
|
+
`;
|
|
160
194
|
}
|
|
161
195
|
}
|
|
162
196
|
|
|
@@ -173,19 +207,18 @@ const backendErrorSchema = z.object({
|
|
|
173
207
|
*/
|
|
174
208
|
export function parsePlError(
|
|
175
209
|
error: string,
|
|
176
|
-
|
|
177
210
|
resource?: ResourceId,
|
|
178
211
|
resourceType?: ResourceType,
|
|
179
212
|
field?: string,
|
|
180
213
|
): PlErrorReport {
|
|
181
214
|
const parsed = backendErrorSchema.parse(JSON.parse(error));
|
|
182
|
-
const
|
|
215
|
+
const errors = parseSubErrors(parsed.message);
|
|
183
216
|
|
|
184
217
|
return new PlErrorReport(
|
|
185
218
|
error,
|
|
186
219
|
parsed.errorType,
|
|
187
220
|
parsed.message,
|
|
188
|
-
|
|
221
|
+
errors,
|
|
189
222
|
|
|
190
223
|
field,
|
|
191
224
|
resource,
|