@milaboratories/pl-errors 1.1.68 → 1.1.70
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.cjs +11 -15
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -2
- package/dist/parsed_error.cjs +157 -209
- package/dist/parsed_error.cjs.map +1 -1
- package/dist/parsed_error.d.ts +59 -56
- package/dist/parsed_error.js +157 -207
- package/dist/parsed_error.js.map +1 -1
- package/package.json +10 -10
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/parsed_error.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.
|
|
11
|
-
exports.
|
|
12
|
-
exports.PlTengoError = parsed_error.PlTengoError;
|
|
13
|
-
exports.parsePlError = parsed_error.parsePlError;
|
|
14
|
-
exports.parseSubErrors = parsed_error.parseSubErrors;
|
|
15
|
-
//# sourceMappingURL=index.cjs.map
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_parsed_error = require('./parsed_error.cjs');
|
|
3
|
+
|
|
4
|
+
exports.PlErrorReport = require_parsed_error.PlErrorReport;
|
|
5
|
+
exports.PlInternalError = require_parsed_error.PlInternalError;
|
|
6
|
+
exports.PlMonetizationError = require_parsed_error.PlMonetizationError;
|
|
7
|
+
exports.PlQuickJSError = require_parsed_error.PlQuickJSError;
|
|
8
|
+
exports.PlRunnerError = require_parsed_error.PlRunnerError;
|
|
9
|
+
exports.PlTengoError = require_parsed_error.PlTengoError;
|
|
10
|
+
exports.parsePlError = require_parsed_error.parsePlError;
|
|
11
|
+
exports.parseSubErrors = require_parsed_error.parseSubErrors;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { PlCoreError, PlErrorReport, PlInternalError, PlMonetizationError, PlQuickJSError, PlRunnerError, PlTengoError, parsePlError, parseSubErrors } from "./parsed_error.js";
|
|
2
|
+
export { PlCoreError, PlErrorReport, PlInternalError, PlMonetizationError, PlQuickJSError, PlRunnerError, PlTengoError, parsePlError, parseSubErrors };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { PlErrorReport, PlInternalError, PlMonetizationError, PlQuickJSError, PlRunnerError, PlTengoError, parsePlError, parseSubErrors } from "./parsed_error.js";
|
|
2
|
+
|
|
3
|
+
export { PlErrorReport, PlInternalError, PlMonetizationError, PlQuickJSError, PlRunnerError, PlTengoError, parsePlError, parseSubErrors };
|
package/dist/parsed_error.cjs
CHANGED
|
@@ -1,163 +1,126 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var plClient = require('@milaboratories/pl-client');
|
|
5
|
-
var tsHelpers = require('@milaboratories/ts-helpers');
|
|
1
|
+
let zod = require("zod");
|
|
2
|
+
let _milaboratories_pl_client = require("@milaboratories/pl-client");
|
|
3
|
+
let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
|
|
6
4
|
|
|
5
|
+
//#region src/parsed_error.ts
|
|
7
6
|
/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */
|
|
8
7
|
/** The error that comes from QuickJS. */
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.stack = stack;
|
|
21
|
-
const causeMsg = "fullMessage" in cause && typeof cause.fullMessage === "string"
|
|
22
|
-
? cause.fullMessage
|
|
23
|
-
: cause.message;
|
|
24
|
-
this.fullMessage = `PlQuickJSError: ${causeMsg}
|
|
8
|
+
var PlQuickJSError = class extends Error {
|
|
9
|
+
stack;
|
|
10
|
+
fullMessage;
|
|
11
|
+
constructor(quickJSError, cause) {
|
|
12
|
+
super(`PlQuickJSError: ${cause.message}`, { cause });
|
|
13
|
+
this.name = "PlQuickJSError";
|
|
14
|
+
let stack = (0, _milaboratories_ts_helpers.notEmpty)(quickJSError.stack);
|
|
15
|
+
stack = stack.replace(quickJSError.message, "");
|
|
16
|
+
stack = stack.replace((0, _milaboratories_ts_helpers.notEmpty)(cause.message), "");
|
|
17
|
+
this.stack = stack;
|
|
18
|
+
this.fullMessage = `PlQuickJSError: ${"fullMessage" in cause && typeof cause.fullMessage === "string" ? cause.fullMessage : cause.message}
|
|
25
19
|
QuickJS stacktrace:
|
|
26
20
|
${this.stack}
|
|
27
21
|
`;
|
|
28
|
-
|
|
29
|
-
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
30
24
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
/** Could be several different errors, the name is from AggregateError. */
|
|
51
|
-
errors,
|
|
52
|
-
/** Optional info about a resource where the error happened. */
|
|
53
|
-
fieldName, resource, resourceType) {
|
|
54
|
-
const errorMessages = errors.map((e) => e.message).join("\n\n");
|
|
55
|
-
const errorFullMessages = errors.map((e) => e.fullMessage).join("\n\n");
|
|
56
|
-
super(`PlErrorReport: ${errorMessages}`);
|
|
57
|
-
this.rawBackendMessage = rawBackendMessage;
|
|
58
|
-
this.plErrorType = plErrorType;
|
|
59
|
-
this.plMessage = plMessage;
|
|
60
|
-
this.errors = errors;
|
|
61
|
-
this.fieldName = fieldName;
|
|
62
|
-
this.resource = resource;
|
|
63
|
-
this.resourceType = resourceType;
|
|
64
|
-
this.name = "PlErrorReport";
|
|
65
|
-
const rt = this.resourceType ? `${plClient.resourceTypeToString(this.resourceType)},` : "";
|
|
66
|
-
const r = this.resource ? plClient.resourceIdToString(this.resource) : "";
|
|
67
|
-
const f = this.fieldName ? `/${this.fieldName}` : "";
|
|
68
|
-
const errType = this.plErrorType ? `error type: ${this.plErrorType}` : "";
|
|
69
|
-
this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
|
|
70
|
-
${errType}
|
|
25
|
+
* A parsed error from the Pl backend.
|
|
26
|
+
* It contains several suberrors, which could be one or different causes of the error.
|
|
27
|
+
*/
|
|
28
|
+
var PlErrorReport = class extends Error {
|
|
29
|
+
fullMessage;
|
|
30
|
+
constructor(rawBackendMessage, plErrorType, plMessage, errors, fieldName, resource, resourceType) {
|
|
31
|
+
const errorMessages = errors.map((e) => e.message).join("\n\n");
|
|
32
|
+
const errorFullMessages = errors.map((e) => e.fullMessage).join("\n\n");
|
|
33
|
+
super(`PlErrorReport: ${errorMessages}`);
|
|
34
|
+
this.rawBackendMessage = rawBackendMessage;
|
|
35
|
+
this.plErrorType = plErrorType;
|
|
36
|
+
this.plMessage = plMessage;
|
|
37
|
+
this.errors = errors;
|
|
38
|
+
this.fieldName = fieldName;
|
|
39
|
+
this.resource = resource;
|
|
40
|
+
this.resourceType = resourceType;
|
|
41
|
+
this.name = "PlErrorReport";
|
|
42
|
+
this.fullMessage = `PlErrorReport: resource: ${this.resourceType ? `${(0, _milaboratories_pl_client.resourceTypeToString)(this.resourceType)},` : ""} ${this.resource ? (0, _milaboratories_pl_client.resourceIdToString)(this.resource) : ""}${this.fieldName ? `/${this.fieldName}` : ""}
|
|
43
|
+
${this.plErrorType ? `error type: ${this.plErrorType}` : ""}
|
|
71
44
|
${errorFullMessages}
|
|
72
45
|
`;
|
|
73
|
-
|
|
74
|
-
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
75
48
|
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
49
|
+
* An general error when we couldn't parse the cause.
|
|
50
|
+
*/
|
|
51
|
+
var PlInternalError = class extends Error {
|
|
52
|
+
fullMessage;
|
|
53
|
+
constructor(message) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.message = message;
|
|
56
|
+
this.name = "PlInternalError";
|
|
57
|
+
this.fullMessage = `PlInternalError: ${message}`;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
88
60
|
/**
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
tengoStacktrace;
|
|
96
|
-
fullMessage;
|
|
97
|
-
constructor(rawBackendMessage, templateName, tengoMessage, tengoStacktrace) {
|
|
98
|
-
const msg = `PlTengoError:
|
|
61
|
+
* Happens when workflow template panics.
|
|
62
|
+
*/
|
|
63
|
+
var PlTengoError = class extends Error {
|
|
64
|
+
fullMessage;
|
|
65
|
+
constructor(rawBackendMessage, templateName, tengoMessage, tengoStacktrace) {
|
|
66
|
+
const msg = `PlTengoError:
|
|
99
67
|
message:
|
|
100
68
|
${tengoMessage}
|
|
101
69
|
template: ${templateName}
|
|
102
70
|
tengo stacktrace:
|
|
103
71
|
${tengoStacktrace}
|
|
104
72
|
`;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
73
|
+
super(msg);
|
|
74
|
+
this.rawBackendMessage = rawBackendMessage;
|
|
75
|
+
this.templateName = templateName;
|
|
76
|
+
this.tengoMessage = tengoMessage;
|
|
77
|
+
this.tengoStacktrace = tengoStacktrace;
|
|
78
|
+
this.name = "PlTengoError";
|
|
79
|
+
this.fullMessage = `${msg}
|
|
112
80
|
raw message:
|
|
113
81
|
${this.rawBackendMessage}
|
|
114
82
|
`;
|
|
115
|
-
|
|
116
|
-
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
117
85
|
/**
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
stdout;
|
|
125
|
-
workingDirectory;
|
|
126
|
-
fullMessage;
|
|
127
|
-
constructor(rawBackendMessage, commandName, exitCode, stdout, workingDirectory) {
|
|
128
|
-
const msg = `PlRunnerError:
|
|
86
|
+
* Happens when a command fails to run.
|
|
87
|
+
*/
|
|
88
|
+
var PlRunnerError = class extends Error {
|
|
89
|
+
fullMessage;
|
|
90
|
+
constructor(rawBackendMessage, commandName, exitCode, stdout, workingDirectory) {
|
|
91
|
+
const msg = `PlRunnerError:
|
|
129
92
|
command: ${commandName}
|
|
130
93
|
exit code: ${exitCode}
|
|
131
94
|
working directory: ${workingDirectory}
|
|
132
95
|
stdout:
|
|
133
96
|
${stdout}`;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
97
|
+
super(msg);
|
|
98
|
+
this.rawBackendMessage = rawBackendMessage;
|
|
99
|
+
this.commandName = commandName;
|
|
100
|
+
this.exitCode = exitCode;
|
|
101
|
+
this.stdout = stdout;
|
|
102
|
+
this.workingDirectory = workingDirectory;
|
|
103
|
+
this.name = "PlRunnerError";
|
|
104
|
+
this.fullMessage = `
|
|
142
105
|
${msg}
|
|
143
106
|
raw message:
|
|
144
107
|
${this.rawBackendMessage}
|
|
145
108
|
`;
|
|
146
|
-
|
|
147
|
-
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
148
111
|
/**
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
112
|
+
* Happens when a monetization command fails to run.
|
|
113
|
+
*/
|
|
114
|
+
var PlMonetizationError = class extends PlRunnerError {
|
|
115
|
+
fullMessage;
|
|
116
|
+
constructor(rawBackendMessage, commandName, exitCode, stdout, workingDirectory) {
|
|
117
|
+
super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);
|
|
118
|
+
const msg = `Monetizaiton error:
|
|
156
119
|
${this.stdout}
|
|
157
120
|
`;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
121
|
+
this.message = msg;
|
|
122
|
+
this.name = "PlMonetizationError";
|
|
123
|
+
this.fullMessage = `
|
|
161
124
|
${msg}
|
|
162
125
|
command: ${this.commandName}
|
|
163
126
|
exit code: ${this.exitCode}
|
|
@@ -166,100 +129,85 @@ working directory: ${this.workingDirectory}
|
|
|
166
129
|
raw message:
|
|
167
130
|
${this.rawBackendMessage}
|
|
168
131
|
`;
|
|
169
|
-
|
|
170
|
-
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
171
134
|
/**
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const backendErrorSchema = zod.z
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
})
|
|
179
|
-
.passthrough();
|
|
135
|
+
* How the Pl backend represents an error.
|
|
136
|
+
*/
|
|
137
|
+
const backendErrorSchema = zod.z.object({
|
|
138
|
+
errorType: zod.z.string().default(""),
|
|
139
|
+
message: zod.z.string()
|
|
140
|
+
}).passthrough();
|
|
180
141
|
/**
|
|
181
|
-
|
|
182
|
-
|
|
142
|
+
* Parses a Pl error and suberrors from the Pl backend.
|
|
143
|
+
*/
|
|
183
144
|
function parsePlError(error, resource, resourceType, field) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const errors = parseSubErrors(parsed.data.message);
|
|
189
|
-
return new PlErrorReport(error, parsed.data.errorType, parsed.data.message, errors, field, resource, resourceType);
|
|
145
|
+
const parsed = backendErrorSchema.safeParse(JSON.parse(error));
|
|
146
|
+
if (!parsed.success) throw new Error(`parsePlError: failed to parse the message, got ${error}`);
|
|
147
|
+
const errors = parseSubErrors(parsed.data.message);
|
|
148
|
+
return new PlErrorReport(error, parsed.data.errorType, parsed.data.message, errors, field, resource, resourceType);
|
|
190
149
|
}
|
|
191
150
|
/**
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
151
|
+
* Reduces over the lines of the pl error message
|
|
152
|
+
* to extract messages, and categorizes them.
|
|
153
|
+
*/
|
|
195
154
|
function parseSubErrors(message) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
state.result.push(parseCoreError(text));
|
|
216
|
-
state.value = [];
|
|
217
|
-
}
|
|
218
|
-
state.value.push(line);
|
|
219
|
-
}
|
|
220
|
-
const text = state.value.join("\n");
|
|
221
|
-
state.result.push(parseCoreError(text));
|
|
222
|
-
return state.result;
|
|
155
|
+
const state = {
|
|
156
|
+
stage: "initial",
|
|
157
|
+
value: [],
|
|
158
|
+
result: []
|
|
159
|
+
};
|
|
160
|
+
for (const line of message.split("\n")) {
|
|
161
|
+
if (state.stage == "initial") state.stage = "path";
|
|
162
|
+
else if (state.stage == "path" && line.startsWith("---")) {} else if (state.stage == "path" && !isPath(line)) state.stage = "message";
|
|
163
|
+
else if (state.stage == "message" && isPath(line)) {
|
|
164
|
+
state.stage = "path";
|
|
165
|
+
const text = state.value.join("\n");
|
|
166
|
+
state.result.push(parseCoreError(text));
|
|
167
|
+
state.value = [];
|
|
168
|
+
}
|
|
169
|
+
state.value.push(line);
|
|
170
|
+
}
|
|
171
|
+
const text = state.value.join("\n");
|
|
172
|
+
state.result.push(parseCoreError(text));
|
|
173
|
+
return state.result;
|
|
223
174
|
}
|
|
224
175
|
function isPath(line) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
176
|
+
for (const fieldType of [
|
|
177
|
+
"U",
|
|
178
|
+
"I",
|
|
179
|
+
"O",
|
|
180
|
+
"S",
|
|
181
|
+
"OTW",
|
|
182
|
+
"D",
|
|
183
|
+
"MTW"
|
|
184
|
+
]) if (line.startsWith(`[${fieldType}]`)) return true;
|
|
185
|
+
return false;
|
|
230
186
|
}
|
|
231
187
|
/**
|
|
232
|
-
|
|
233
|
-
|
|
188
|
+
* Parses a suberror from the Pl backend.
|
|
189
|
+
*/
|
|
234
190
|
function parseCoreError(message) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const workflowMatch = message.match(workflowErrorRegex);
|
|
253
|
-
if (workflowMatch) {
|
|
254
|
-
const templateName = workflowMatch[1];
|
|
255
|
-
const errorMessage = workflowMatch[2];
|
|
256
|
-
const stackTrace = workflowMatch[3];
|
|
257
|
-
return new PlTengoError(message, templateName, errorMessage, stackTrace);
|
|
258
|
-
}
|
|
259
|
-
// if we couldn't parse the error, return a general error.
|
|
260
|
-
return new PlInternalError(message);
|
|
191
|
+
const match = message.match(/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]*)/);
|
|
192
|
+
if (match) {
|
|
193
|
+
const workingDirectory = match[1];
|
|
194
|
+
const command = match[2];
|
|
195
|
+
const exitCode = parseInt(match[3], 10);
|
|
196
|
+
const stdout = match[4].trim();
|
|
197
|
+
if (command.endsWith(`mnz-client`) && exitCode == 1) return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);
|
|
198
|
+
return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);
|
|
199
|
+
}
|
|
200
|
+
const workflowMatch = message.match(/cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/);
|
|
201
|
+
if (workflowMatch) {
|
|
202
|
+
const templateName = workflowMatch[1];
|
|
203
|
+
const errorMessage = workflowMatch[2];
|
|
204
|
+
const stackTrace = workflowMatch[3];
|
|
205
|
+
return new PlTengoError(message, templateName, errorMessage, stackTrace);
|
|
206
|
+
}
|
|
207
|
+
return new PlInternalError(message);
|
|
261
208
|
}
|
|
262
209
|
|
|
210
|
+
//#endregion
|
|
263
211
|
exports.PlErrorReport = PlErrorReport;
|
|
264
212
|
exports.PlInternalError = PlInternalError;
|
|
265
213
|
exports.PlMonetizationError = PlMonetizationError;
|
|
@@ -268,4 +216,4 @@ exports.PlRunnerError = PlRunnerError;
|
|
|
268
216
|
exports.PlTengoError = PlTengoError;
|
|
269
217
|
exports.parsePlError = parsePlError;
|
|
270
218
|
exports.parseSubErrors = parseSubErrors;
|
|
271
|
-
//# sourceMappingURL=parsed_error.cjs.map
|
|
219
|
+
//# sourceMappingURL=parsed_error.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed_error.cjs","sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from \"zod\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport { resourceIdToString, resourceTypeToString } from \"@milaboratories/pl-client\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(quickJSError: Error, cause: Error) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = \"PlQuickJSError\";\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, \"\");\n stack = stack.replace(notEmpty(cause.message), \"\");\n\n this.stack = stack;\n\n const causeMsg =\n \"fullMessage\" in cause && typeof cause.fullMessage === \"string\"\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join(\"\\n\\n\");\n const errorFullMessages = errors.map((e) => e.fullMessage).join(\"\\n\\n\");\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = \"PlErrorReport\";\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : \"\";\n const r = this.resource ? resourceIdToString(this.resource) : \"\";\n const f = this.fieldName ? `/${this.fieldName}` : \"\";\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : \"\";\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(public readonly message: string) {\n super(message);\n this.name = \"PlInternalError\";\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = \"PlTengoError\";\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = \"PlRunnerError\";\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = \"PlMonetizationError\";\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z\n .object({\n errorType: z.string().default(\"\"),\n message: z.string(),\n })\n .passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: \"initial\" as \"initial\" | \"path\" | \"message\",\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split(\"\\n\")) {\n if (state.stage == \"initial\") {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = \"path\";\n } else if (state.stage == \"path\" && line.startsWith(\"---\")) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == \"path\" && !isPath(line)) {\n state.stage = \"message\";\n } else if (state.stage == \"message\" && isPath(line)) {\n state.stage = \"path\";\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of [\"U\", \"I\", \"O\", \"S\", \"OTW\", \"D\", \"MTW\"]) {\n if (line.startsWith(`[${fieldType}]`)) return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex =\n /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex =\n /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"names":["notEmpty","resourceTypeToString","resourceIdToString","z"],"mappings":";;;;;;AAAA;AAOA;AACM,MAAO,cAAe,SAAQ,KAAK,CAAA;AAChC,IAAA,KAAK;AACL,IAAA,WAAW;IAElB,WAAA,CAAY,YAAmB,EAAE,KAAY,EAAA;QAC3C,KAAK,CAAC,CAAA,gBAAA,EAAmB,KAAK,CAAC,OAAO,CAAA,CAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AACpD,QAAA,IAAI,CAAC,IAAI,GAAG,gBAAgB;;;QAI5B,IAAI,KAAK,GAAGA,kBAAQ,CAAC,YAAY,CAAC,KAAK,CAAC;QACxC,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;AAC/C,QAAA,KAAK,GAAG,KAAK,CAAC,OAAO,CAACA,kBAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;AAElD,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;QAElB,MAAM,QAAQ,GACZ,aAAa,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK;cACnD,KAAK,CAAC;AACR,cAAE,KAAK,CAAC,OAAO;AAEnB,QAAA,IAAI,CAAC,WAAW,GAAG,CAAA,gBAAA,EAAmB,QAAQ;;AAEhD,EAAA,IAAI,CAAC,KAAK;CACX;IACC;AACD;AAED;;;AAGG;AACG,MAAO,aAAc,SAAQ,KAAK,CAAA;AAKpB,IAAA,iBAAA;AAGA,IAAA,WAAA;AAGA,IAAA,SAAA;AAGA,IAAA,MAAA;AAGA,IAAA,SAAA;AACA,IAAA,QAAA;AACA,IAAA,YAAA;AAlBF,IAAA,WAAW;AAE3B,IAAA,WAAA;;IAEkB,iBAAyB;;IAGzB,WAAmB;;IAGnB,SAAiB;;IAGjB,MAAqB;;IAGrB,SAAkB,EAClB,QAAqB,EACrB,YAA2B,EAAA;QAE3C,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/D,MAAM,iBAAiB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;AAEvE,QAAA,KAAK,CAAC,CAAA,eAAA,EAAkB,aAAa,CAAA,CAAE,CAAC;QAnBxB,IAAA,CAAA,iBAAiB,GAAjB,iBAAiB;QAGjB,IAAA,CAAA,WAAW,GAAX,WAAW;QAGX,IAAA,CAAA,SAAS,GAAT,SAAS;QAGT,IAAA,CAAA,MAAM,GAAN,MAAM;QAGN,IAAA,CAAA,SAAS,GAAT,SAAS;QACT,IAAA,CAAA,QAAQ,GAAR,QAAQ;QACR,IAAA,CAAA,YAAY,GAAZ,YAAY;AAM5B,QAAA,IAAI,CAAC,IAAI,GAAG,eAAe;QAE3B,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,GAAG,CAAA,EAAGC,6BAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA,CAAA,CAAG,GAAG,EAAE;AACjF,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,GAAGC,2BAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;AAChE,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,GAAG,CAAA,CAAA,EAAI,IAAI,CAAC,SAAS,CAAA,CAAE,GAAG,EAAE;AACpD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,CAAA,YAAA,EAAe,IAAI,CAAC,WAAW,CAAA,CAAE,GAAG,EAAE;QAEzE,IAAI,CAAC,WAAW,GAAG,CAAA,yBAAA,EAA4B,EAAE,CAAA,CAAA,EAAI,CAAC,GAAG,CAAC;EAC5D,OAAO;EACP,iBAAiB;CAClB;IACC;AACD;AAOD;;AAEG;AACG,MAAO,eAAgB,SAAQ,KAAK,CAAA;AAEZ,IAAA,OAAA;AADZ,IAAA,WAAW;AAC3B,IAAA,WAAA,CAA4B,OAAe,EAAA;QACzC,KAAK,CAAC,OAAO,CAAC;QADY,IAAA,CAAA,OAAO,GAAP,OAAO;AAEjC,QAAA,IAAI,CAAC,IAAI,GAAG,iBAAiB;AAC7B,QAAA,IAAI,CAAC,WAAW,GAAG,CAAA,iBAAA,EAAoB,OAAO,EAAE;IAClD;AACD;AAED;;AAEG;AACG,MAAO,YAAa,SAAQ,KAAK,CAAA;AAInB,IAAA,iBAAA;AACA,IAAA,YAAA;AACA,IAAA,YAAA;AACA,IAAA,eAAA;AANF,IAAA,WAAW;AAE3B,IAAA,WAAA,CACkB,iBAAyB,EACzB,YAAoB,EACpB,YAAoB,EACpB,eAAuB,EAAA;AAEvC,QAAA,MAAM,GAAG,GAAG,CAAA;;EAEd,YAAY;YACF,YAAY;;EAEtB,eAAe;CAChB;QAEG,KAAK,CAAC,GAAG,CAAC;QAbM,IAAA,CAAA,iBAAiB,GAAjB,iBAAiB;QACjB,IAAA,CAAA,YAAY,GAAZ,YAAY;QACZ,IAAA,CAAA,YAAY,GAAZ,YAAY;QACZ,IAAA,CAAA,eAAe,GAAf,eAAe;AAW/B,QAAA,IAAI,CAAC,IAAI,GAAG,cAAc;AAE1B,QAAA,IAAI,CAAC,WAAW,GAAG,CAAA,EAAG,GAAG;;AAE3B,EAAA,IAAI,CAAC,iBAAiB;CACvB;IACC;AACD;AAED;;AAEG;AACG,MAAO,aAAc,SAAQ,KAAK,CAAA;AAIpB,IAAA,iBAAA;AACA,IAAA,WAAA;AACA,IAAA,QAAA;AACA,IAAA,MAAA;AACA,IAAA,gBAAA;AAPF,IAAA,WAAW;IAE3B,WAAA,CACkB,iBAAyB,EACzB,WAAmB,EACnB,QAAgB,EAChB,MAAc,EACd,gBAAwB,EAAA;AAExC,QAAA,MAAM,GAAG,GAAG,CAAA;WACL,WAAW;aACT,QAAQ;qBACA,gBAAgB;;AAEnC,EAAA,MAAM,EAAE;QAEN,KAAK,CAAC,GAAG,CAAC;QAbM,IAAA,CAAA,iBAAiB,GAAjB,iBAAiB;QACjB,IAAA,CAAA,WAAW,GAAX,WAAW;QACX,IAAA,CAAA,QAAQ,GAAR,QAAQ;QACR,IAAA,CAAA,MAAM,GAAN,MAAM;QACN,IAAA,CAAA,gBAAgB,GAAhB,gBAAgB;AAUhC,QAAA,IAAI,CAAC,IAAI,GAAG,eAAe;QAC3B,IAAI,CAAC,WAAW,GAAG;EACrB,GAAG;;AAEH,EAAA,IAAI,CAAC,iBAAiB;CACvB;IACC;AACD;AAED;;AAEG;AACG,MAAO,mBAAoB,SAAQ,aAAa,CAAA;AACpC,IAAA,WAAW;IAC3B,WAAA,CACE,iBAAyB,EACzB,WAAmB,EACnB,QAAgB,EAChB,MAAc,EACd,gBAAwB,EAAA;QAExB,KAAK,CAAC,iBAAiB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC;AACzE,QAAA,MAAM,GAAG,GAAG,CAAA;AACd,EAAA,IAAI,CAAC,MAAM;CACZ;AAEG,QAAA,IAAI,CAAC,OAAO,GAAG,GAAG;AAClB,QAAA,IAAI,CAAC,IAAI,GAAG,qBAAqB;QAEjC,IAAI,CAAC,WAAW,GAAG;EACrB,GAAG;AACM,SAAA,EAAA,IAAI,CAAC,WAAW;AACd,WAAA,EAAA,IAAI,CAAC,QAAQ;AACL,mBAAA,EAAA,IAAI,CAAC,gBAAgB;;;AAGxC,EAAA,IAAI,CAAC,iBAAiB;CACvB;IACC;AACD;AAED;;AAEG;AACH,MAAM,kBAAkB,GAAGC;AACxB,KAAA,MAAM,CAAC;IACN,SAAS,EAAEA,KAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;AACjC,IAAA,OAAO,EAAEA,KAAC,CAAC,MAAM,EAAE;CACpB;AACA,KAAA,WAAW,EAAE;AAEhB;;AAEG;AACG,SAAU,YAAY,CAC1B,KAAa,EACb,QAAqB,EACrB,YAA2B,EAC3B,KAAc,EAAA;AAEd,IAAA,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC9D,IAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;AACnB,QAAA,MAAM,IAAI,KAAK,CAAC,kDAAkD,KAAK,CAAA,CAAE,CAAC;IAC5E;IAEA,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;IAElD,OAAO,IAAI,aAAa,CACtB,KAAK,EACL,MAAM,CAAC,IAAI,CAAC,SAAS,EACrB,MAAM,CAAC,IAAI,CAAC,OAAO,EACnB,MAAM,EAEN,KAAK,EACL,QAAQ,EACR,YAAY,CACb;AACH;AAEA;;;AAGG;AACG,SAAU,cAAc,CAAC,OAAe,EAAA;;AAE5C,IAAA,MAAM,KAAK,GAAG;AACZ,QAAA,KAAK,EAAE,SAA2C;AAClD,QAAA,KAAK,EAAE,EAAc;AACrB,QAAA,MAAM,EAAE,EAAmB;KAC5B;IAED,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AACtC,QAAA,IAAI,KAAK,CAAC,KAAK,IAAI,SAAS,EAAE;;;AAG5B,YAAA,KAAK,CAAC,KAAK,GAAG,MAAM;QACtB;AAAO,aAAA,IAAI,KAAK,CAAC,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;AAGrD,aAAA,IAAI,KAAK,CAAC,KAAK,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;AACjD,YAAA,KAAK,CAAC,KAAK,GAAG,SAAS;QACzB;aAAO,IAAI,KAAK,CAAC,KAAK,IAAI,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;AACnD,YAAA,KAAK,CAAC,KAAK,GAAG,MAAM;YACpB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;YACnC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AACvC,YAAA,KAAK,CAAC,KAAK,GAAG,EAAE;QAClB;AAEA,QAAA,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB;IAEA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;IACnC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAEvC,OAAO,KAAK,CAAC,MAAM;AACrB;AAEA,SAAS,MAAM,CAAC,IAAY,EAAA;AAC1B,IAAA,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE;AAC/D,QAAA,IAAI,IAAI,CAAC,UAAU,CAAC,CAAA,CAAA,EAAI,SAAS,GAAG,CAAC;AAAE,YAAA,OAAO,IAAI;IACpD;AAEA,IAAA,OAAO,KAAK;AACd;AAEA;;AAEG;AACH,SAAS,cAAc,CAAC,OAAe,EAAA;;;IAGrC,MAAM,gBAAgB,GACpB,uJAAuJ;IACzJ,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC7C,IAAI,KAAK,EAAE;AACT,QAAA,MAAM,gBAAgB,GAAG,KAAK,CAAC,CAAC,CAAC;AACjC,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;QACxB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAE9B,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA,UAAA,CAAY,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE;AACnD,YAAA,OAAO,IAAI,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC;QACtF;AAEA,QAAA,OAAO,IAAI,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC;IAChF;;;IAIA,MAAM,kBAAkB,GACtB,iFAAiF;IACnF,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC;IACvD,IAAI,aAAa,EAAE;AACjB,QAAA,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC;AACrC,QAAA,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC;AACrC,QAAA,MAAM,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC;QAEnC,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,CAAC;IAC1E;;AAGA,IAAA,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC;AACrC;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"parsed_error.cjs","names":["z"],"sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from \"zod\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport { resourceIdToString, resourceTypeToString } from \"@milaboratories/pl-client\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(quickJSError: Error, cause: Error) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = \"PlQuickJSError\";\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, \"\");\n stack = stack.replace(notEmpty(cause.message), \"\");\n\n this.stack = stack;\n\n const causeMsg =\n \"fullMessage\" in cause && typeof cause.fullMessage === \"string\"\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join(\"\\n\\n\");\n const errorFullMessages = errors.map((e) => e.fullMessage).join(\"\\n\\n\");\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = \"PlErrorReport\";\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : \"\";\n const r = this.resource ? resourceIdToString(this.resource) : \"\";\n const f = this.fieldName ? `/${this.fieldName}` : \"\";\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : \"\";\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(public readonly message: string) {\n super(message);\n this.name = \"PlInternalError\";\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = \"PlTengoError\";\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = \"PlRunnerError\";\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = \"PlMonetizationError\";\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z\n .object({\n errorType: z.string().default(\"\"),\n message: z.string(),\n })\n .passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: \"initial\" as \"initial\" | \"path\" | \"message\",\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split(\"\\n\")) {\n if (state.stage == \"initial\") {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = \"path\";\n } else if (state.stage == \"path\" && line.startsWith(\"---\")) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == \"path\" && !isPath(line)) {\n state.stage = \"message\";\n } else if (state.stage == \"message\" && isPath(line)) {\n state.stage = \"path\";\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of [\"U\", \"I\", \"O\", \"S\", \"OTW\", \"D\", \"MTW\"]) {\n if (line.startsWith(`[${fieldType}]`)) return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex =\n /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex =\n /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"mappings":"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"}
|
package/dist/parsed_error.d.ts
CHANGED
|
@@ -1,90 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { ResourceId, ResourceType } from "@milaboratories/pl-client";
|
|
2
|
+
|
|
3
|
+
//#region src/parsed_error.d.ts
|
|
3
4
|
/** The error that comes from QuickJS. */
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
declare class PlQuickJSError extends Error {
|
|
6
|
+
stack: string;
|
|
7
|
+
fullMessage: string;
|
|
8
|
+
constructor(quickJSError: Error, cause: Error);
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* A parsed error from the Pl backend.
|
|
11
12
|
* It contains several suberrors, which could be one or different causes of the error.
|
|
12
13
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
declare class PlErrorReport extends Error {
|
|
15
|
+
/** Full message from the Pl backend. */
|
|
16
|
+
readonly rawBackendMessage: string;
|
|
17
|
+
/** Either CID conflict or a error from controller. */
|
|
18
|
+
readonly plErrorType: string;
|
|
19
|
+
/** Parsed pl backend message that will be futher parsed into suberrors. */
|
|
20
|
+
readonly plMessage: string;
|
|
21
|
+
/** Could be several different errors, the name is from AggregateError. */
|
|
22
|
+
readonly errors: PlCoreError[];
|
|
23
|
+
/** Optional info about a resource where the error happened. */
|
|
24
|
+
readonly fieldName?: string | undefined;
|
|
25
|
+
readonly resource?: ResourceId | undefined;
|
|
26
|
+
readonly resourceType?: ResourceType | undefined;
|
|
27
|
+
readonly fullMessage: string;
|
|
28
|
+
constructor(/** Full message from the Pl backend. */
|
|
29
|
+
|
|
30
|
+
rawBackendMessage: string, /** Either CID conflict or a error from controller. */
|
|
31
|
+
|
|
32
|
+
plErrorType: string, /** Parsed pl backend message that will be futher parsed into suberrors. */
|
|
33
|
+
|
|
34
|
+
plMessage: string, /** Could be several different errors, the name is from AggregateError. */
|
|
35
|
+
|
|
36
|
+
errors: PlCoreError[], /** Optional info about a resource where the error happened. */
|
|
37
|
+
|
|
38
|
+
fieldName?: string | undefined, resource?: ResourceId | undefined, resourceType?: ResourceType | undefined);
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* A suberror of a parsed error.
|
|
41
42
|
*/
|
|
42
|
-
|
|
43
|
+
type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;
|
|
43
44
|
/**
|
|
44
45
|
* An general error when we couldn't parse the cause.
|
|
45
46
|
*/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
declare class PlInternalError extends Error {
|
|
48
|
+
readonly message: string;
|
|
49
|
+
readonly fullMessage: string;
|
|
50
|
+
constructor(message: string);
|
|
50
51
|
}
|
|
51
52
|
/**
|
|
52
53
|
* Happens when workflow template panics.
|
|
53
54
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
declare class PlTengoError extends Error {
|
|
56
|
+
readonly rawBackendMessage: string;
|
|
57
|
+
readonly templateName: string;
|
|
58
|
+
readonly tengoMessage: string;
|
|
59
|
+
readonly tengoStacktrace: string;
|
|
60
|
+
readonly fullMessage: string;
|
|
61
|
+
constructor(rawBackendMessage: string, templateName: string, tengoMessage: string, tengoStacktrace: string);
|
|
61
62
|
}
|
|
62
63
|
/**
|
|
63
64
|
* Happens when a command fails to run.
|
|
64
65
|
*/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
declare class PlRunnerError extends Error {
|
|
67
|
+
readonly rawBackendMessage: string;
|
|
68
|
+
readonly commandName: string;
|
|
69
|
+
readonly exitCode: number;
|
|
70
|
+
readonly stdout: string;
|
|
71
|
+
readonly workingDirectory: string;
|
|
72
|
+
readonly fullMessage: string;
|
|
73
|
+
constructor(rawBackendMessage: string, commandName: string, exitCode: number, stdout: string, workingDirectory: string);
|
|
73
74
|
}
|
|
74
75
|
/**
|
|
75
76
|
* Happens when a monetization command fails to run.
|
|
76
77
|
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
declare class PlMonetizationError extends PlRunnerError {
|
|
79
|
+
readonly fullMessage: string;
|
|
80
|
+
constructor(rawBackendMessage: string, commandName: string, exitCode: number, stdout: string, workingDirectory: string);
|
|
80
81
|
}
|
|
81
82
|
/**
|
|
82
83
|
* Parses a Pl error and suberrors from the Pl backend.
|
|
83
84
|
*/
|
|
84
|
-
|
|
85
|
+
declare function parsePlError(error: string, resource?: ResourceId, resourceType?: ResourceType, field?: string): PlErrorReport;
|
|
85
86
|
/**
|
|
86
87
|
* Reduces over the lines of the pl error message
|
|
87
88
|
* to extract messages, and categorizes them.
|
|
88
89
|
*/
|
|
89
|
-
|
|
90
|
+
declare function parseSubErrors(message: string): PlCoreError[];
|
|
91
|
+
//#endregion
|
|
92
|
+
export { PlCoreError, PlErrorReport, PlInternalError, PlMonetizationError, PlQuickJSError, PlRunnerError, PlTengoError, parsePlError, parseSubErrors };
|
|
90
93
|
//# sourceMappingURL=parsed_error.d.ts.map
|
package/dist/parsed_error.js
CHANGED
|
@@ -1,161 +1,126 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import {
|
|
3
|
-
import { notEmpty } from
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { resourceIdToString, resourceTypeToString } from "@milaboratories/pl-client";
|
|
3
|
+
import { notEmpty } from "@milaboratories/ts-helpers";
|
|
4
4
|
|
|
5
|
+
//#region src/parsed_error.ts
|
|
5
6
|
/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */
|
|
6
7
|
/** The error that comes from QuickJS. */
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
this.stack = stack;
|
|
19
|
-
const causeMsg = "fullMessage" in cause && typeof cause.fullMessage === "string"
|
|
20
|
-
? cause.fullMessage
|
|
21
|
-
: cause.message;
|
|
22
|
-
this.fullMessage = `PlQuickJSError: ${causeMsg}
|
|
8
|
+
var PlQuickJSError = class extends Error {
|
|
9
|
+
stack;
|
|
10
|
+
fullMessage;
|
|
11
|
+
constructor(quickJSError, cause) {
|
|
12
|
+
super(`PlQuickJSError: ${cause.message}`, { cause });
|
|
13
|
+
this.name = "PlQuickJSError";
|
|
14
|
+
let stack = notEmpty(quickJSError.stack);
|
|
15
|
+
stack = stack.replace(quickJSError.message, "");
|
|
16
|
+
stack = stack.replace(notEmpty(cause.message), "");
|
|
17
|
+
this.stack = stack;
|
|
18
|
+
this.fullMessage = `PlQuickJSError: ${"fullMessage" in cause && typeof cause.fullMessage === "string" ? cause.fullMessage : cause.message}
|
|
23
19
|
QuickJS stacktrace:
|
|
24
20
|
${this.stack}
|
|
25
21
|
`;
|
|
26
|
-
|
|
27
|
-
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
28
24
|
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
/** Could be several different errors, the name is from AggregateError. */
|
|
49
|
-
errors,
|
|
50
|
-
/** Optional info about a resource where the error happened. */
|
|
51
|
-
fieldName, resource, resourceType) {
|
|
52
|
-
const errorMessages = errors.map((e) => e.message).join("\n\n");
|
|
53
|
-
const errorFullMessages = errors.map((e) => e.fullMessage).join("\n\n");
|
|
54
|
-
super(`PlErrorReport: ${errorMessages}`);
|
|
55
|
-
this.rawBackendMessage = rawBackendMessage;
|
|
56
|
-
this.plErrorType = plErrorType;
|
|
57
|
-
this.plMessage = plMessage;
|
|
58
|
-
this.errors = errors;
|
|
59
|
-
this.fieldName = fieldName;
|
|
60
|
-
this.resource = resource;
|
|
61
|
-
this.resourceType = resourceType;
|
|
62
|
-
this.name = "PlErrorReport";
|
|
63
|
-
const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : "";
|
|
64
|
-
const r = this.resource ? resourceIdToString(this.resource) : "";
|
|
65
|
-
const f = this.fieldName ? `/${this.fieldName}` : "";
|
|
66
|
-
const errType = this.plErrorType ? `error type: ${this.plErrorType}` : "";
|
|
67
|
-
this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}
|
|
68
|
-
${errType}
|
|
25
|
+
* A parsed error from the Pl backend.
|
|
26
|
+
* It contains several suberrors, which could be one or different causes of the error.
|
|
27
|
+
*/
|
|
28
|
+
var PlErrorReport = class extends Error {
|
|
29
|
+
fullMessage;
|
|
30
|
+
constructor(rawBackendMessage, plErrorType, plMessage, errors, fieldName, resource, resourceType) {
|
|
31
|
+
const errorMessages = errors.map((e) => e.message).join("\n\n");
|
|
32
|
+
const errorFullMessages = errors.map((e) => e.fullMessage).join("\n\n");
|
|
33
|
+
super(`PlErrorReport: ${errorMessages}`);
|
|
34
|
+
this.rawBackendMessage = rawBackendMessage;
|
|
35
|
+
this.plErrorType = plErrorType;
|
|
36
|
+
this.plMessage = plMessage;
|
|
37
|
+
this.errors = errors;
|
|
38
|
+
this.fieldName = fieldName;
|
|
39
|
+
this.resource = resource;
|
|
40
|
+
this.resourceType = resourceType;
|
|
41
|
+
this.name = "PlErrorReport";
|
|
42
|
+
this.fullMessage = `PlErrorReport: resource: ${this.resourceType ? `${resourceTypeToString(this.resourceType)},` : ""} ${this.resource ? resourceIdToString(this.resource) : ""}${this.fieldName ? `/${this.fieldName}` : ""}
|
|
43
|
+
${this.plErrorType ? `error type: ${this.plErrorType}` : ""}
|
|
69
44
|
${errorFullMessages}
|
|
70
45
|
`;
|
|
71
|
-
|
|
72
|
-
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
73
48
|
/**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
49
|
+
* An general error when we couldn't parse the cause.
|
|
50
|
+
*/
|
|
51
|
+
var PlInternalError = class extends Error {
|
|
52
|
+
fullMessage;
|
|
53
|
+
constructor(message) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.message = message;
|
|
56
|
+
this.name = "PlInternalError";
|
|
57
|
+
this.fullMessage = `PlInternalError: ${message}`;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
86
60
|
/**
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
tengoStacktrace;
|
|
94
|
-
fullMessage;
|
|
95
|
-
constructor(rawBackendMessage, templateName, tengoMessage, tengoStacktrace) {
|
|
96
|
-
const msg = `PlTengoError:
|
|
61
|
+
* Happens when workflow template panics.
|
|
62
|
+
*/
|
|
63
|
+
var PlTengoError = class extends Error {
|
|
64
|
+
fullMessage;
|
|
65
|
+
constructor(rawBackendMessage, templateName, tengoMessage, tengoStacktrace) {
|
|
66
|
+
const msg = `PlTengoError:
|
|
97
67
|
message:
|
|
98
68
|
${tengoMessage}
|
|
99
69
|
template: ${templateName}
|
|
100
70
|
tengo stacktrace:
|
|
101
71
|
${tengoStacktrace}
|
|
102
72
|
`;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
73
|
+
super(msg);
|
|
74
|
+
this.rawBackendMessage = rawBackendMessage;
|
|
75
|
+
this.templateName = templateName;
|
|
76
|
+
this.tengoMessage = tengoMessage;
|
|
77
|
+
this.tengoStacktrace = tengoStacktrace;
|
|
78
|
+
this.name = "PlTengoError";
|
|
79
|
+
this.fullMessage = `${msg}
|
|
110
80
|
raw message:
|
|
111
81
|
${this.rawBackendMessage}
|
|
112
82
|
`;
|
|
113
|
-
|
|
114
|
-
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
115
85
|
/**
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
stdout;
|
|
123
|
-
workingDirectory;
|
|
124
|
-
fullMessage;
|
|
125
|
-
constructor(rawBackendMessage, commandName, exitCode, stdout, workingDirectory) {
|
|
126
|
-
const msg = `PlRunnerError:
|
|
86
|
+
* Happens when a command fails to run.
|
|
87
|
+
*/
|
|
88
|
+
var PlRunnerError = class extends Error {
|
|
89
|
+
fullMessage;
|
|
90
|
+
constructor(rawBackendMessage, commandName, exitCode, stdout, workingDirectory) {
|
|
91
|
+
const msg = `PlRunnerError:
|
|
127
92
|
command: ${commandName}
|
|
128
93
|
exit code: ${exitCode}
|
|
129
94
|
working directory: ${workingDirectory}
|
|
130
95
|
stdout:
|
|
131
96
|
${stdout}`;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
97
|
+
super(msg);
|
|
98
|
+
this.rawBackendMessage = rawBackendMessage;
|
|
99
|
+
this.commandName = commandName;
|
|
100
|
+
this.exitCode = exitCode;
|
|
101
|
+
this.stdout = stdout;
|
|
102
|
+
this.workingDirectory = workingDirectory;
|
|
103
|
+
this.name = "PlRunnerError";
|
|
104
|
+
this.fullMessage = `
|
|
140
105
|
${msg}
|
|
141
106
|
raw message:
|
|
142
107
|
${this.rawBackendMessage}
|
|
143
108
|
`;
|
|
144
|
-
|
|
145
|
-
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
146
111
|
/**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
112
|
+
* Happens when a monetization command fails to run.
|
|
113
|
+
*/
|
|
114
|
+
var PlMonetizationError = class extends PlRunnerError {
|
|
115
|
+
fullMessage;
|
|
116
|
+
constructor(rawBackendMessage, commandName, exitCode, stdout, workingDirectory) {
|
|
117
|
+
super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);
|
|
118
|
+
const msg = `Monetizaiton error:
|
|
154
119
|
${this.stdout}
|
|
155
120
|
`;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
121
|
+
this.message = msg;
|
|
122
|
+
this.name = "PlMonetizationError";
|
|
123
|
+
this.fullMessage = `
|
|
159
124
|
${msg}
|
|
160
125
|
command: ${this.commandName}
|
|
161
126
|
exit code: ${this.exitCode}
|
|
@@ -164,99 +129,84 @@ working directory: ${this.workingDirectory}
|
|
|
164
129
|
raw message:
|
|
165
130
|
${this.rawBackendMessage}
|
|
166
131
|
`;
|
|
167
|
-
|
|
168
|
-
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
169
134
|
/**
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const backendErrorSchema = z
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
})
|
|
177
|
-
.passthrough();
|
|
135
|
+
* How the Pl backend represents an error.
|
|
136
|
+
*/
|
|
137
|
+
const backendErrorSchema = z.object({
|
|
138
|
+
errorType: z.string().default(""),
|
|
139
|
+
message: z.string()
|
|
140
|
+
}).passthrough();
|
|
178
141
|
/**
|
|
179
|
-
|
|
180
|
-
|
|
142
|
+
* Parses a Pl error and suberrors from the Pl backend.
|
|
143
|
+
*/
|
|
181
144
|
function parsePlError(error, resource, resourceType, field) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const errors = parseSubErrors(parsed.data.message);
|
|
187
|
-
return new PlErrorReport(error, parsed.data.errorType, parsed.data.message, errors, field, resource, resourceType);
|
|
145
|
+
const parsed = backendErrorSchema.safeParse(JSON.parse(error));
|
|
146
|
+
if (!parsed.success) throw new Error(`parsePlError: failed to parse the message, got ${error}`);
|
|
147
|
+
const errors = parseSubErrors(parsed.data.message);
|
|
148
|
+
return new PlErrorReport(error, parsed.data.errorType, parsed.data.message, errors, field, resource, resourceType);
|
|
188
149
|
}
|
|
189
150
|
/**
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
151
|
+
* Reduces over the lines of the pl error message
|
|
152
|
+
* to extract messages, and categorizes them.
|
|
153
|
+
*/
|
|
193
154
|
function parseSubErrors(message) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
state.result.push(parseCoreError(text));
|
|
214
|
-
state.value = [];
|
|
215
|
-
}
|
|
216
|
-
state.value.push(line);
|
|
217
|
-
}
|
|
218
|
-
const text = state.value.join("\n");
|
|
219
|
-
state.result.push(parseCoreError(text));
|
|
220
|
-
return state.result;
|
|
155
|
+
const state = {
|
|
156
|
+
stage: "initial",
|
|
157
|
+
value: [],
|
|
158
|
+
result: []
|
|
159
|
+
};
|
|
160
|
+
for (const line of message.split("\n")) {
|
|
161
|
+
if (state.stage == "initial") state.stage = "path";
|
|
162
|
+
else if (state.stage == "path" && line.startsWith("---")) {} else if (state.stage == "path" && !isPath(line)) state.stage = "message";
|
|
163
|
+
else if (state.stage == "message" && isPath(line)) {
|
|
164
|
+
state.stage = "path";
|
|
165
|
+
const text = state.value.join("\n");
|
|
166
|
+
state.result.push(parseCoreError(text));
|
|
167
|
+
state.value = [];
|
|
168
|
+
}
|
|
169
|
+
state.value.push(line);
|
|
170
|
+
}
|
|
171
|
+
const text = state.value.join("\n");
|
|
172
|
+
state.result.push(parseCoreError(text));
|
|
173
|
+
return state.result;
|
|
221
174
|
}
|
|
222
175
|
function isPath(line) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
176
|
+
for (const fieldType of [
|
|
177
|
+
"U",
|
|
178
|
+
"I",
|
|
179
|
+
"O",
|
|
180
|
+
"S",
|
|
181
|
+
"OTW",
|
|
182
|
+
"D",
|
|
183
|
+
"MTW"
|
|
184
|
+
]) if (line.startsWith(`[${fieldType}]`)) return true;
|
|
185
|
+
return false;
|
|
228
186
|
}
|
|
229
187
|
/**
|
|
230
|
-
|
|
231
|
-
|
|
188
|
+
* Parses a suberror from the Pl backend.
|
|
189
|
+
*/
|
|
232
190
|
function parseCoreError(message) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
const workflowMatch = message.match(workflowErrorRegex);
|
|
251
|
-
if (workflowMatch) {
|
|
252
|
-
const templateName = workflowMatch[1];
|
|
253
|
-
const errorMessage = workflowMatch[2];
|
|
254
|
-
const stackTrace = workflowMatch[3];
|
|
255
|
-
return new PlTengoError(message, templateName, errorMessage, stackTrace);
|
|
256
|
-
}
|
|
257
|
-
// if we couldn't parse the error, return a general error.
|
|
258
|
-
return new PlInternalError(message);
|
|
191
|
+
const match = message.match(/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]*)/);
|
|
192
|
+
if (match) {
|
|
193
|
+
const workingDirectory = match[1];
|
|
194
|
+
const command = match[2];
|
|
195
|
+
const exitCode = parseInt(match[3], 10);
|
|
196
|
+
const stdout = match[4].trim();
|
|
197
|
+
if (command.endsWith(`mnz-client`) && exitCode == 1) return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);
|
|
198
|
+
return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);
|
|
199
|
+
}
|
|
200
|
+
const workflowMatch = message.match(/cannot eval code: cannot eval template: template: (.+)\n\t(.*?)\n\t(at [\s\S]*)/);
|
|
201
|
+
if (workflowMatch) {
|
|
202
|
+
const templateName = workflowMatch[1];
|
|
203
|
+
const errorMessage = workflowMatch[2];
|
|
204
|
+
const stackTrace = workflowMatch[3];
|
|
205
|
+
return new PlTengoError(message, templateName, errorMessage, stackTrace);
|
|
206
|
+
}
|
|
207
|
+
return new PlInternalError(message);
|
|
259
208
|
}
|
|
260
209
|
|
|
210
|
+
//#endregion
|
|
261
211
|
export { PlErrorReport, PlInternalError, PlMonetizationError, PlQuickJSError, PlRunnerError, PlTengoError, parsePlError, parseSubErrors };
|
|
262
|
-
//# sourceMappingURL=parsed_error.js.map
|
|
212
|
+
//# sourceMappingURL=parsed_error.js.map
|
package/dist/parsed_error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed_error.js","sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from \"zod\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport { resourceIdToString, resourceTypeToString } from \"@milaboratories/pl-client\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(quickJSError: Error, cause: Error) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = \"PlQuickJSError\";\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, \"\");\n stack = stack.replace(notEmpty(cause.message), \"\");\n\n this.stack = stack;\n\n const causeMsg =\n \"fullMessage\" in cause && typeof cause.fullMessage === \"string\"\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join(\"\\n\\n\");\n const errorFullMessages = errors.map((e) => e.fullMessage).join(\"\\n\\n\");\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = \"PlErrorReport\";\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : \"\";\n const r = this.resource ? resourceIdToString(this.resource) : \"\";\n const f = this.fieldName ? `/${this.fieldName}` : \"\";\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : \"\";\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(public readonly message: string) {\n super(message);\n this.name = \"PlInternalError\";\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = \"PlTengoError\";\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = \"PlRunnerError\";\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = \"PlMonetizationError\";\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z\n .object({\n errorType: z.string().default(\"\"),\n message: z.string(),\n })\n .passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: \"initial\" as \"initial\" | \"path\" | \"message\",\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split(\"\\n\")) {\n if (state.stage == \"initial\") {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = \"path\";\n } else if (state.stage == \"path\" && line.startsWith(\"---\")) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == \"path\" && !isPath(line)) {\n state.stage = \"message\";\n } else if (state.stage == \"message\" && isPath(line)) {\n state.stage = \"path\";\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of [\"U\", \"I\", \"O\", \"S\", \"OTW\", \"D\", \"MTW\"]) {\n if (line.startsWith(`[${fieldType}]`)) return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex =\n /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex =\n /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"parsed_error.js","names":[],"sources":["../src/parsed_error.ts"],"sourcesContent":["/** Pl Backend throws arbitrary errors, and we're trying to parse them here. */\n\nimport { z } from \"zod\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport { resourceIdToString, resourceTypeToString } from \"@milaboratories/pl-client\";\nimport { notEmpty } from \"@milaboratories/ts-helpers\";\n\n/** The error that comes from QuickJS. */\nexport class PlQuickJSError extends Error {\n public stack: string;\n public fullMessage: string;\n\n constructor(quickJSError: Error, cause: Error) {\n super(`PlQuickJSError: ${cause.message}`, { cause });\n this.name = \"PlQuickJSError\";\n\n // QuickJS wraps the error with the name and the message,\n // but we need another format.\n let stack = notEmpty(quickJSError.stack);\n stack = stack.replace(quickJSError.message, \"\");\n stack = stack.replace(notEmpty(cause.message), \"\");\n\n this.stack = stack;\n\n const causeMsg =\n \"fullMessage\" in cause && typeof cause.fullMessage === \"string\"\n ? cause.fullMessage\n : cause.message;\n\n this.fullMessage = `PlQuickJSError: ${causeMsg}\nQuickJS stacktrace:\n${this.stack}\n`;\n }\n}\n\n/**\n * A parsed error from the Pl backend.\n * It contains several suberrors, which could be one or different causes of the error.\n */\nexport class PlErrorReport extends Error {\n public readonly fullMessage: string;\n\n constructor(\n /** Full message from the Pl backend. */\n public readonly rawBackendMessage: string,\n\n /** Either CID conflict or a error from controller. */\n public readonly plErrorType: string,\n\n /** Parsed pl backend message that will be futher parsed into suberrors. */\n public readonly plMessage: string,\n\n /** Could be several different errors, the name is from AggregateError. */\n public readonly errors: PlCoreError[],\n\n /** Optional info about a resource where the error happened. */\n public readonly fieldName?: string,\n public readonly resource?: ResourceId,\n public readonly resourceType?: ResourceType,\n ) {\n const errorMessages = errors.map((e) => e.message).join(\"\\n\\n\");\n const errorFullMessages = errors.map((e) => e.fullMessage).join(\"\\n\\n\");\n\n super(`PlErrorReport: ${errorMessages}`);\n this.name = \"PlErrorReport\";\n\n const rt = this.resourceType ? `${resourceTypeToString(this.resourceType)},` : \"\";\n const r = this.resource ? resourceIdToString(this.resource) : \"\";\n const f = this.fieldName ? `/${this.fieldName}` : \"\";\n const errType = this.plErrorType ? `error type: ${this.plErrorType}` : \"\";\n\n this.fullMessage = `PlErrorReport: resource: ${rt} ${r}${f}\n${errType}\n${errorFullMessages}\n`;\n }\n}\n\n/**\n * A suberror of a parsed error.\n */\nexport type PlCoreError = PlInternalError | PlTengoError | PlRunnerError | PlMonetizationError;\n\n/**\n * An general error when we couldn't parse the cause.\n */\nexport class PlInternalError extends Error {\n public readonly fullMessage: string;\n constructor(public readonly message: string) {\n super(message);\n this.name = \"PlInternalError\";\n this.fullMessage = `PlInternalError: ${message}`;\n }\n}\n\n/**\n * Happens when workflow template panics.\n */\nexport class PlTengoError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly templateName: string,\n public readonly tengoMessage: string,\n public readonly tengoStacktrace: string,\n ) {\n const msg = `PlTengoError:\nmessage:\n${tengoMessage}\ntemplate: ${templateName}\ntengo stacktrace:\n${tengoStacktrace}\n`;\n\n super(msg);\n this.name = \"PlTengoError\";\n\n this.fullMessage = `${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a command fails to run.\n */\nexport class PlRunnerError extends Error {\n public readonly fullMessage: string;\n\n constructor(\n public readonly rawBackendMessage: string,\n public readonly commandName: string,\n public readonly exitCode: number,\n public readonly stdout: string,\n public readonly workingDirectory: string,\n ) {\n const msg = `PlRunnerError:\ncommand: ${commandName}\nexit code: ${exitCode}\nworking directory: ${workingDirectory}\nstdout:\n${stdout}`;\n\n super(msg);\n this.name = \"PlRunnerError\";\n this.fullMessage = `\n${msg}\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * Happens when a monetization command fails to run.\n */\nexport class PlMonetizationError extends PlRunnerError {\n public readonly fullMessage: string;\n constructor(\n rawBackendMessage: string,\n commandName: string,\n exitCode: number,\n stdout: string,\n workingDirectory: string,\n ) {\n super(rawBackendMessage, commandName, exitCode, stdout, workingDirectory);\n const msg = `Monetizaiton error:\n${this.stdout}\n`;\n\n this.message = msg;\n this.name = \"PlMonetizationError\";\n\n this.fullMessage = `\n${msg}\ncommand: ${this.commandName}\nexit code: ${this.exitCode}\nworking directory: ${this.workingDirectory}\n\nraw message:\n${this.rawBackendMessage}\n`;\n }\n}\n\n/**\n * How the Pl backend represents an error.\n */\nconst backendErrorSchema = z\n .object({\n errorType: z.string().default(\"\"),\n message: z.string(),\n })\n .passthrough();\n\n/**\n * Parses a Pl error and suberrors from the Pl backend.\n */\nexport function parsePlError(\n error: string,\n resource?: ResourceId,\n resourceType?: ResourceType,\n field?: string,\n): PlErrorReport {\n const parsed = backendErrorSchema.safeParse(JSON.parse(error));\n if (!parsed.success) {\n throw new Error(`parsePlError: failed to parse the message, got ${error}`);\n }\n\n const errors = parseSubErrors(parsed.data.message);\n\n return new PlErrorReport(\n error,\n parsed.data.errorType,\n parsed.data.message,\n errors,\n\n field,\n resource,\n resourceType,\n );\n}\n\n/**\n * Reduces over the lines of the pl error message\n * to extract messages, and categorizes them.\n */\nexport function parseSubErrors(message: string): PlCoreError[] {\n // the state of this reducing function\n const state = {\n stage: \"initial\" as \"initial\" | \"path\" | \"message\",\n value: [] as string[],\n result: [] as PlCoreError[],\n };\n\n for (const line of message.split(\"\\n\")) {\n if (state.stage == \"initial\") {\n // we need initial stage because apparently the first line\n // of the error doesn't have [I], but is a path line.\n state.stage = \"path\";\n } else if (state.stage == \"path\" && line.startsWith(\"---\")) {\n // we should add stack separator to path stage\n // without break stage processing\n } else if (state.stage == \"path\" && !isPath(line)) {\n state.stage = \"message\";\n } else if (state.stage == \"message\" && isPath(line)) {\n state.stage = \"path\";\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n state.value = [];\n }\n\n state.value.push(line);\n }\n\n const text = state.value.join(\"\\n\");\n state.result.push(parseCoreError(text));\n\n return state.result;\n}\n\nfunction isPath(line: string): boolean {\n for (const fieldType of [\"U\", \"I\", \"O\", \"S\", \"OTW\", \"D\", \"MTW\"]) {\n if (line.startsWith(`[${fieldType}]`)) return true;\n }\n\n return false;\n}\n\n/**\n * Parses a suberror from the Pl backend.\n */\nfunction parseCoreError(message: string): PlCoreError {\n // trying to parse a runner or monetization error.\n // https://regex101.com/r/tmKLj7/1\n const runnerErrorRegex =\n /working directory: \"(.*)\"[\\s\\S]failed to run command: \"([^\"]+)\" exited with code (\\d+)\\.[\\s\\S]*?Here is the latest command output:[\\s\\S]*?\\t([\\s\\S]*)/;\n const match = message.match(runnerErrorRegex);\n if (match) {\n const workingDirectory = match[1];\n const command = match[2];\n const exitCode = parseInt(match[3], 10);\n const stdout = match[4].trim();\n\n if (command.endsWith(`mnz-client`) && exitCode == 1) {\n return new PlMonetizationError(message, command, exitCode, stdout, workingDirectory);\n }\n\n return new PlRunnerError(message, command, exitCode, stdout, workingDirectory);\n }\n\n // trying to parse a Tengo error.\n // https://regex101.com/r/1a7RpO/1\n const workflowErrorRegex =\n /cannot eval code: cannot eval template: template: (.+)\\n\\t(.*?)\\n\\t(at [\\s\\S]*)/;\n const workflowMatch = message.match(workflowErrorRegex);\n if (workflowMatch) {\n const templateName = workflowMatch[1];\n const errorMessage = workflowMatch[2];\n const stackTrace = workflowMatch[3];\n\n return new PlTengoError(message, templateName, errorMessage, stackTrace);\n }\n\n // if we couldn't parse the error, return a general error.\n return new PlInternalError(message);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-errors",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.70",
|
|
4
4
|
"description": "Parsing errors from Pl backend",
|
|
5
5
|
"files": [
|
|
6
6
|
"./dist/**/*",
|
|
@@ -18,17 +18,17 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"zod": "~3.23.8",
|
|
21
|
-
"@milaboratories/pl-client": "2.17.
|
|
22
|
-
"@milaboratories/ts-helpers": "1.7.
|
|
21
|
+
"@milaboratories/pl-client": "2.17.8",
|
|
22
|
+
"@milaboratories/ts-helpers": "1.7.3"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@vitest/coverage-istanbul": "^4.0.
|
|
26
|
-
"typescript": "~5.
|
|
27
|
-
"vitest": "^4.0.
|
|
28
|
-
"@milaboratories/
|
|
29
|
-
"@milaboratories/
|
|
30
|
-
"@milaboratories/ts-configs": "1.2.
|
|
31
|
-
"@milaboratories/pl-error-like": "1.12.
|
|
25
|
+
"@vitest/coverage-istanbul": "^4.0.18",
|
|
26
|
+
"typescript": "~5.9.3",
|
|
27
|
+
"vitest": "^4.0.18",
|
|
28
|
+
"@milaboratories/build-configs": "1.5.1",
|
|
29
|
+
"@milaboratories/ts-builder": "1.2.13",
|
|
30
|
+
"@milaboratories/ts-configs": "1.2.2",
|
|
31
|
+
"@milaboratories/pl-error-like": "1.12.9"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "ts-builder build --target node",
|
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parsed_error.d.ts","sourceRoot":"","sources":["../src/parsed_error.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAG/E,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAI1E,yCAAyC;AACzC,qBAAa,cAAe,SAAQ,KAAK;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;gBAEf,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;CAsB9C;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAIpC,wCAAwC;aACxB,iBAAiB,EAAE,MAAM;IAEzC,sDAAsD;aACtC,WAAW,EAAE,MAAM;IAEnC,2EAA2E;aAC3D,SAAS,EAAE,MAAM;IAEjC,0EAA0E;aAC1D,MAAM,EAAE,WAAW,EAAE;IAErC,+DAA+D;aAC/C,SAAS,CAAC,EAAE,MAAM;aAClB,QAAQ,CAAC,EAAE,UAAU;aACrB,YAAY,CAAC,EAAE,YAAY;IAlB7C,SAAgB,WAAW,EAAE,MAAM,CAAC;;IAGlC,wCAAwC;IACxB,iBAAiB,EAAE,MAAM;IAEzC,sDAAsD;IACtC,WAAW,EAAE,MAAM;IAEnC,2EAA2E;IAC3D,SAAS,EAAE,MAAM;IAEjC,0EAA0E;IAC1D,MAAM,EAAE,WAAW,EAAE;IAErC,+DAA+D;IAC/C,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,QAAQ,CAAC,EAAE,UAAU,YAAA,EACrB,YAAY,CAAC,EAAE,YAAY,YAAA;CAkB9C;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,YAAY,GAAG,aAAa,GAAG,mBAAmB,CAAC;AAE/F;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAEZ,OAAO,EAAE,MAAM;IAD3C,SAAgB,WAAW,EAAE,MAAM,CAAC;gBACR,OAAO,EAAE,MAAM;CAK5C;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;aAInB,iBAAiB,EAAE,MAAM;aACzB,YAAY,EAAE,MAAM;aACpB,YAAY,EAAE,MAAM;aACpB,eAAe,EAAE,MAAM;IANzC,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAGlB,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM;CAkB1C;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;aAIpB,iBAAiB,EAAE,MAAM;aACzB,WAAW,EAAE,MAAM;aACnB,QAAQ,EAAE,MAAM;aAChB,MAAM,EAAE,MAAM;aACd,gBAAgB,EAAE,MAAM;IAP1C,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAGlB,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM;CAiB3C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,aAAa;IACpD,SAAgB,WAAW,EAAE,MAAM,CAAC;gBAElC,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM;CAoB3B;AAYD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,UAAU,EACrB,YAAY,CAAC,EAAE,YAAY,EAC3B,KAAK,CAAC,EAAE,MAAM,GACb,aAAa,CAkBf;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CAgC7D"}
|