@milaboratories/pl-errors 1.0.2 → 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 { ResourceId, resourceIdToString, ResourceType, 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\n } else if (state.stage == 'path' && !isPath(line)) {\n state.stage = 'message';\n\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 { ResourceId, resourceIdToString, ResourceType, 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\n } else if (state.stage == 'path' && !isPath(line)) {\n state.stage = 'message';\n\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,EAAE,UAAU,EAAsB,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAE/G;;;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,CA+B7D"}
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.2",
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,18 +18,21 @@
18
18
  ],
19
19
  "dependencies": {
20
20
  "zod": "~3.23.8",
21
- "@milaboratories/pl-client": "2.7.13"
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
- "@milaboratories/eslint-config": "^1.0.2"
30
+ "@milaboratories/eslint-config": "^1.0.4"
29
31
  },
30
32
  "scripts": {
31
33
  "type-check": "tsc --noEmit --composite false",
32
34
  "build": "vite build",
35
+ "lint": "eslint .",
33
36
  "test": "vitest",
34
37
  "do-pack": "rm -f *.tgz && pnpm pack && mv *.tgz package.tgz"
35
38
  }
@@ -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
+ });
@@ -1,18 +1,51 @@
1
1
  /** Pl Backend throws arbitrary errors, and we're trying to parse them here. */
2
2
 
3
- import { z } from "zod";
4
- import { ResourceId, resourceIdToString, ResourceType, resourceTypeToString } from "@milaboratories/pl-client";
3
+ import { z } from 'zod';
4
+ import type { ResourceId, ResourceType } from '@milaboratories/pl-client';
5
+ import { resourceIdToString, resourceTypeToString } from '@milaboratories/pl-client';
6
+ import { notEmpty } from '@milaboratories/ts-helpers';
7
+
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
+ }
5
38
 
6
39
  /**
7
40
  * A parsed error from the Pl backend.
8
41
  * It contains several suberrors, which could be one or different causes of the error.
9
42
  */
10
43
  export class PlErrorReport extends Error {
11
- message: string;
44
+ public readonly fullMessage: string;
12
45
 
13
46
  constructor(
14
47
  /** Full message from the Pl backend. */
15
- public readonly fullMessage: string,
48
+ public readonly rawBackendMessage: string,
16
49
 
17
50
  /** Either CID conflict or a error from controller. */
18
51
  public readonly plErrorType: string,
@@ -28,21 +61,21 @@ export class PlErrorReport extends Error {
28
61
  public readonly resource?: ResourceId,
29
62
  public readonly resourceType?: ResourceType,
30
63
  ) {
31
- 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}`);
32
68
  this.name = 'PlErrorReport';
33
- this.message = this.toString();
34
- }
35
69
 
36
- toString() {
37
70
  const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : '';
38
71
  const r = this.resource ? resourceIdToString(this.resource) : '';
39
72
  const f = this.fieldName ? `/${this.fieldName}` : '';
40
73
  const errType = this.plErrorType ? `error type: ${this.plErrorType}` : '';
41
- const subErrors = this.errors.map(e => e.message).join('\n\n');
42
74
 
43
- return `PlErrorReport: resource: ${rt} ${r}${f}
75
+ this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
44
76
  ${errType}
45
- ${subErrors}`;
77
+ ${errorFullMessages}
78
+ `;
46
79
  }
47
80
  }
48
81
 
@@ -59,11 +92,13 @@ export type PlCoreError =
59
92
  * An general error when we couldn't parse the cause.
60
93
  */
61
94
  export class PlInternalError extends Error {
95
+ public readonly fullMessage: string;
62
96
  constructor(
63
97
  public readonly message: string,
64
98
  ) {
65
99
  super(message);
66
100
  this.name = 'PlInternalError';
101
+ this.fullMessage = `PlInternalError: ${message}`;
67
102
  }
68
103
  }
69
104
 
@@ -71,29 +106,29 @@ export class PlInternalError extends Error {
71
106
  * Happens when workflow template panics.
72
107
  */
73
108
  export class PlTengoError extends Error {
74
- message: string;
109
+ public readonly fullMessage: string;
75
110
 
76
111
  constructor(
77
- public readonly fullMessage: string,
112
+ public readonly rawBackendMessage: string,
78
113
  public readonly templateName: string,
79
114
  public readonly tengoMessage: string,
80
115
  public readonly tengoStacktrace: string,
81
116
  ) {
82
- super(fullMessage);
83
- this.name = 'PlWorkflowError';
84
- this.message = this.toString();
85
- }
86
-
87
- toString() {
88
- return `PlWorkflowError:
89
- template: ${this.templateName}
117
+ const msg = `PlTengoError:
90
118
  message:
91
- ${this.tengoMessage}
119
+ ${tengoMessage}
120
+ template: ${templateName}
92
121
  tengo stacktrace:
93
- ${this.tengoStacktrace}
122
+ ${tengoStacktrace}
123
+ `;
94
124
 
95
- full message:
96
- ${this.fullMessage}`;
125
+ super(msg);
126
+ this.name = 'PlTengoError';
127
+
128
+ this.fullMessage = `${msg}
129
+ raw message:
130
+ ${this.rawBackendMessage}
131
+ `;
97
132
  }
98
133
  }
99
134
 
@@ -101,30 +136,29 @@ ${this.fullMessage}`;
101
136
  * Happens when a command fails to run.
102
137
  */
103
138
  export class PlRunnerError extends Error {
104
- message: string;
139
+ public readonly fullMessage: string;
105
140
 
106
141
  constructor(
107
- public readonly fullMessage: string,
142
+ public readonly rawBackendMessage: string,
108
143
  public readonly commandName: string,
109
144
  public readonly exitCode: number,
110
145
  public readonly stdout: string,
111
146
  public readonly workingDirectory: string,
112
147
  ) {
113
- super(fullMessage);
114
- this.name = 'PlRunnerError';
115
- this.message = this.toString();
116
- }
117
-
118
- toString() {
119
- return `PlRunnerError:
120
- command: ${this.commandName}
121
- exit code: ${this.exitCode}
122
- working directory: ${this.workingDirectory}
148
+ const msg = `PlRunnerError:
149
+ command: ${commandName}
150
+ exit code: ${exitCode}
151
+ working directory: ${workingDirectory}
123
152
  stdout:
124
- ${this.stdout}
153
+ ${stdout}`;
125
154
 
126
- full message:
127
- ${this.fullMessage}`;
155
+ super(msg);
156
+ this.name = 'PlRunnerError';
157
+ this.fullMessage = `
158
+ ${msg}
159
+ raw message:
160
+ ${this.rawBackendMessage}
161
+ `;
128
162
  }
129
163
  }
130
164
 
@@ -132,30 +166,31 @@ ${this.fullMessage}`;
132
166
  * Happens when a monetization command fails to run.
133
167
  */
134
168
  export class PlMonetizationError extends PlRunnerError {
135
- message: string;
136
-
169
+ public readonly fullMessage: string;
137
170
  constructor(
138
- fullMessage: string,
171
+ rawBackendMessage: string,
139
172
  commandName: string,
140
173
  exitCode: number,
141
174
  stdout: string,
142
175
  workingDirectory: string,
143
176
  ) {
144
- 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;
145
183
  this.name = 'PlMonetizationError';
146
- this.message = this.toString();
147
- }
148
184
 
149
- toString() {
150
- return `PlMonetizationError:
185
+ this.fullMessage = `
186
+ ${msg}
151
187
  command: ${this.commandName}
152
188
  exit code: ${this.exitCode}
153
189
  working directory: ${this.workingDirectory}
154
- stdout:
155
- ${this.stdout}
156
190
 
157
- full message:
158
- ${this.fullMessage}`;
191
+ raw message:
192
+ ${this.rawBackendMessage}
193
+ `;
159
194
  }
160
195
  }
161
196
 
@@ -172,19 +207,18 @@ const backendErrorSchema = z.object({
172
207
  */
173
208
  export function parsePlError(
174
209
  error: string,
175
-
176
210
  resource?: ResourceId,
177
211
  resourceType?: ResourceType,
178
212
  field?: string,
179
213
  ): PlErrorReport {
180
214
  const parsed = backendErrorSchema.parse(JSON.parse(error));
181
- const subErrors = parseSubErrors(parsed.message);
215
+ const errors = parseSubErrors(parsed.message);
182
216
 
183
217
  return new PlErrorReport(
184
218
  error,
185
219
  parsed.errorType,
186
220
  parsed.message,
187
- subErrors,
221
+ errors,
188
222
 
189
223
  field,
190
224
  resource,
@@ -209,10 +243,8 @@ export function parseSubErrors(message: string): PlCoreError[] {
209
243
  // we need initial stage because apparently the first line
210
244
  // of the error doesn't have [I], but is a path line.
211
245
  state.stage = 'path';
212
-
213
246
  } else if (state.stage == 'path' && !isPath(line)) {
214
247
  state.stage = 'message';
215
-
216
248
  } else if (state.stage == 'message' && isPath(line)) {
217
249
  state.stage = 'path';
218
250
  const text = state.value.join('\n');