@milaboratories/pl-errors 1.0.3 → 1.0.4

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 CHANGED
@@ -1,33 +1,43 @@
1
- "use strict";var $=Object.defineProperty;var y=(e,r,t)=>r in e?$(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var c=(e,r,t)=>y(e,typeof r!="symbol"?r+"":r,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("zod"),g=require("@milaboratories/pl-client");class d extends Error{constructor(t,o,s,n,i,a,l){super(t);c(this,"message");this.fullMessage=t,this.plErrorType=o,this.plMessage=s,this.errors=n,this.fieldName=i,this.resource=a,this.resourceType=l,this.name="PlErrorReport",this.message=this.toString()}toString(){const t=this.resourceType?`${g.resourceTypeToString(this.resourceType)},`:"",o=this.resource?g.resourceIdToString(this.resource):"",s=this.fieldName?`/${this.fieldName}`:"",n=this.plErrorType?`error type: ${this.plErrorType}`:"",i=this.errors.map(a=>a.message).join(`
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
- `);return`PlErrorReport: resource: ${t} ${o}${s}
4
- ${n}
5
- ${i}`}}class E extends Error{constructor(r){super(r),this.message=r,this.name="PlInternalError"}}class f extends Error{constructor(t,o,s,n){super(t);c(this,"message");this.fullMessage=t,this.templateName=o,this.tengoMessage=s,this.tengoStacktrace=n,this.name="PlWorkflowError",this.message=this.toString()}toString(){return`PlWorkflowError:
6
- template: ${this.templateName}
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
- ${this.tengoMessage}
13
+ ${s}
14
+ template: ${o}
9
15
  tengo stacktrace:
10
- ${this.tengoStacktrace}
11
-
12
- full message:
13
- ${this.fullMessage}`}}class h extends Error{constructor(t,o,s,n,i){super(t);c(this,"message");this.fullMessage=t,this.commandName=o,this.exitCode=s,this.stdout=n,this.workingDirectory=i,this.name="PlRunnerError",this.message=this.toString()}toString(){return`PlRunnerError:
14
- command: ${this.commandName}
15
- exit code: ${this.exitCode}
16
- working directory: ${this.workingDirectory}
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
- full message:
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
- full message:
29
- ${this.fullMessage}`}}const w=u.z.object({errorType:u.z.string(),message:u.z.string()});function T(e,r,t,o){const s=w.parse(JSON.parse(e)),n=P(s.message);return new d(e,s.errorType,s.message,n,o,r,t)}function P(e){const r={stage:"initial",value:[],result:[]};for(const o of e.split(`
30
- `)){if(r.stage=="initial")r.stage="path";else if(r.stage=="path"&&!m(o))r.stage="message";else if(r.stage=="message"&&m(o)){r.stage="path";const s=r.value.join(`
31
- `);r.result.push(p(s)),r.value=[]}r.value.push(o)}const t=r.value.join(`
32
- `);return r.result.push(p(t)),r.result}function m(e){for(const r of["U","I","O","S","OTW","D","MTW"])if(e.startsWith(`[${r}]`))return!0;return!1}function p(e){const r=/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]*)/,t=e.match(r);if(t){const n=t[1],i=t[2],a=parseInt(t[3],10),l=t[4].trim();return i.endsWith("mnz-client")&&a==1?new S(e,i,a,l,n):new h(e,i,a,l,n)}const o=/cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/,s=e.match(o);if(s){const n=s[1],i=s[2],a=s[3];return new f(e,n,i,a)}return new E(e)}exports.PlErrorReport=d;exports.PlInternalError=E;exports.PlMonetizationError=S;exports.PlRunnerError=h;exports.PlTengoError=f;exports.parsePlError=T;exports.parseSubErrors=P;
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 p = Object.defineProperty;
2
- var d = (e, t, r) => t in e ? p(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
- var c = (e, t, r) => d(e, typeof t != "symbol" ? t + "" : t, r);
4
- import { z as u } from "zod";
5
- import { resourceTypeToString as f, resourceIdToString as E } from "@milaboratories/pl-client";
6
- class $ extends Error {
7
- constructor(r, o, s, n, i, a, l) {
8
- super(r);
9
- c(this, "message");
10
- this.fullMessage = r, this.plErrorType = o, this.plMessage = s, this.errors = n, this.fieldName = i, this.resource = a, this.resourceType = l, this.name = "PlErrorReport", this.message = this.toString();
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
- toString() {
13
- const r = this.resourceType ? `${f(this.resourceType)},` : "", o = this.resource ? E(this.resource) : "", s = this.fieldName ? `/${this.fieldName}` : "", n = this.plErrorType ? `error type: ${this.plErrorType}` : "", i = this.errors.map((a) => a.message).join(`
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
- return `PlErrorReport: resource: ${r} ${o}${s}
17
- ${n}
18
- ${i}`;
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 S extends Error {
22
- constructor(t) {
23
- super(t), this.message = t, this.name = "PlInternalError";
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 w extends Error {
46
+ class v extends Error {
27
47
  constructor(r, o, s, n) {
28
- super(r);
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
- ${this.tengoMessage}
50
+ ${s}
51
+ template: ${o}
37
52
  tengo stacktrace:
38
- ${this.tengoStacktrace}
39
-
40
- full message:
41
- ${this.fullMessage}`;
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 g extends Error {
45
- constructor(r, o, s, n, i) {
46
- super(r);
47
- c(this, "message");
48
- this.fullMessage = r, this.commandName = o, this.exitCode = s, this.stdout = n, this.workingDirectory = i, this.name = "PlRunnerError", this.message = this.toString();
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
- ${this.stdout}
57
-
58
- full message:
59
- ${this.fullMessage}`;
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 y extends g {
63
- constructor(r, o, s, n, i) {
64
- super(r, o, s, n, i);
65
- c(this, "message");
66
- this.name = "PlMonetizationError", this.message = this.toString();
67
- }
68
- toString() {
69
- return `PlMonetizationError:
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
- full message:
77
- ${this.fullMessage}`;
93
+ raw message:
94
+ ${this.rawBackendMessage}
95
+ `;
78
96
  }
79
97
  }
80
- const x = u.object({
81
- errorType: u.string(),
82
- message: u.string()
98
+ const I = h.object({
99
+ errorType: h.string(),
100
+ message: h.string()
83
101
  });
84
- function N(e, t, r, o) {
85
- const s = x.parse(JSON.parse(e)), n = T(s.message);
86
- return new $(
87
- e,
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
- t,
110
+ e,
93
111
  r
94
112
  );
95
113
  }
96
- function T(e) {
97
- const t = {
114
+ function N(t) {
115
+ const e = {
98
116
  stage: "initial",
99
117
  value: [],
100
118
  result: []
101
119
  };
102
- for (const o of e.split(`
120
+ for (const o of t.split(`
103
121
  `)) {
104
- if (t.stage == "initial")
105
- t.stage = "path";
106
- else if (t.stage == "path" && !h(o))
107
- t.stage = "message";
108
- else if (t.stage == "message" && h(o)) {
109
- t.stage = "path";
110
- const s = t.value.join(`
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
- t.result.push(m(s)), t.value = [];
130
+ e.result.push(m(s)), e.value = [];
113
131
  }
114
- t.value.push(o);
132
+ e.value.push(o);
115
133
  }
116
- const r = t.value.join(`
134
+ const r = e.value.join(`
117
135
  `);
118
- return t.result.push(m(r)), t.result;
136
+ return e.result.push(m(r)), e.result;
119
137
  }
120
- function h(e) {
121
- for (const t of ["U", "I", "O", "S", "OTW", "D", "MTW"])
122
- if (e.startsWith(`[${t}]`))
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(e) {
127
- const t = /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 = e.match(t);
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], i = r[2], a = parseInt(r[3], 10), l = r[4].trim();
130
- return i.endsWith("mnz-client") && a == 1 ? new y(e, i, a, l, n) : new g(e, i, a, l, n);
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 = e.match(o);
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], i = s[2], a = s[3];
135
- return new w(e, n, i, a);
152
+ const n = s[1], a = s[2], i = s[3];
153
+ return new v(t, n, a, i);
136
154
  }
137
- return new S(e);
155
+ return new R(t);
138
156
  }
139
157
  export {
140
- $ as PlErrorReport,
141
- S as PlInternalError,
142
- y as PlMonetizationError,
143
- g as PlRunnerError,
144
- w as PlTengoError,
145
- N as parsePlError,
146
- T as parseSubErrors
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
@@ -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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"}
@@ -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 fullMessage: string;
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
- message: string;
25
+ readonly fullMessage: string;
20
26
  constructor(
21
27
  /** Full message from the Pl backend. */
22
- fullMessage: string,
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 fullMessage: string;
54
+ readonly rawBackendMessage: string;
49
55
  readonly templateName: string;
50
56
  readonly tengoMessage: string;
51
57
  readonly tengoStacktrace: string;
52
- message: string;
53
- constructor(fullMessage: string, templateName: string, tengoMessage: string, tengoStacktrace: string);
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 fullMessage: string;
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
- message: string;
66
- constructor(fullMessage: string, commandName: string, exitCode: number, stdout: string, workingDirectory: string);
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
- message: string;
74
- constructor(fullMessage: string, commandName: string, exitCode: number, stdout: string, workingDirectory: string);
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;AAG1E;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAIpC,wCAAwC;aACxB,WAAW,EAAE,MAAM;IAEnC,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,OAAO,EAAE,MAAM,CAAC;;IAGd,wCAAwC;IACxB,WAAW,EAAE,MAAM;IAEnC,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;IAO7C,QAAQ;CAWT;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,YAAY,GACZ,aAAa,GACb,mBAAmB,CAAC;AAExB;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAEtB,OAAO,EAAE,MAAM;gBAAf,OAAO,EAAE,MAAM;CAKlC;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;aAInB,WAAW,EAAE,MAAM;aACnB,YAAY,EAAE,MAAM;aACpB,YAAY,EAAE,MAAM;aACpB,eAAe,EAAE,MAAM;IANzC,OAAO,EAAE,MAAM,CAAC;gBAGE,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM;IAOzC,QAAQ;CAWT;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAIpB,WAAW,EAAE,MAAM;aACnB,WAAW,EAAE,MAAM;aACnB,QAAQ,EAAE,MAAM;aAChB,MAAM,EAAE,MAAM;aACd,gBAAgB,EAAE,MAAM;IAP1C,OAAO,EAAE,MAAM,CAAC;gBAGE,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM;IAO1C,QAAQ;CAWT;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,aAAa;IACpD,OAAO,EAAE,MAAM,CAAC;gBAGd,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM;IAO1B,QAAQ;CAWT;AAUD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EAEb,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"}
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",
3
+ "version": "1.0.4",
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/pl-client": "2.7.14"
21
+ "@milaboratories/pl-client": "2.7.14",
22
+ "@milaboratories/ts-helpers": "1.1.5"
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
  },
@@ -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
+ });
@@ -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
- message: string;
44
+ public readonly fullMessage: string;
13
45
 
14
46
  constructor(
15
47
  /** Full message from the Pl backend. */
16
- public readonly fullMessage: string,
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
- super(fullMessage);
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
- return `PlErrorReport: resource: ${rt} ${r}${f}
75
+ this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
45
76
  ${errType}
46
- ${subErrors}`;
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
- message: string;
109
+ public readonly fullMessage: string;
76
110
 
77
111
  constructor(
78
- public readonly fullMessage: string,
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
- super(fullMessage);
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
- ${this.tengoMessage}
119
+ ${tengoMessage}
120
+ template: ${templateName}
93
121
  tengo stacktrace:
94
- ${this.tengoStacktrace}
122
+ ${tengoStacktrace}
123
+ `;
124
+
125
+ super(msg);
126
+ this.name = 'PlTengoError';
95
127
 
96
- full message:
97
- ${this.fullMessage}`;
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
- message: string;
139
+ public readonly fullMessage: string;
106
140
 
107
141
  constructor(
108
- public readonly fullMessage: string,
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
- super(fullMessage);
115
- this.name = 'PlRunnerError';
116
- this.message = this.toString();
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
- ${this.stdout}
153
+ ${stdout}`;
126
154
 
127
- full message:
128
- ${this.fullMessage}`;
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
- message: string;
137
-
169
+ public readonly fullMessage: string;
138
170
  constructor(
139
- fullMessage: string,
171
+ rawBackendMessage: string,
140
172
  commandName: string,
141
173
  exitCode: number,
142
174
  stdout: string,
143
175
  workingDirectory: string,
144
176
  ) {
145
- super(fullMessage, commandName, exitCode, stdout, workingDirectory);
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
- toString() {
151
- return `PlMonetizationError:
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
- full message:
159
- ${this.fullMessage}`;
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 subErrors = parseSubErrors(parsed.message);
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
- subErrors,
221
+ errors,
189
222
 
190
223
  field,
191
224
  resource,