u
This commit is contained in:
@@ -82,11 +82,11 @@ Applet executed successfully
|
|||||||
|
|
||||||
| Status | Description |
|
| Status | Description |
|
||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| 400 | No company selected, invalid path, not a .applet.js file, invalid input, or invalid applet metadata — `{"error":"…"}` |
|
| 400 | No company selected, invalid path, not a .applet.js file, invalid input, invalid applet metadata, or applet runtime error — `{"error":"…"}` |
|
||||||
| 401 | Unauthorized — `{"error":"…"}` |
|
| 401 | Unauthorized — `{"error":"…"}` |
|
||||||
| 403 | Not authorized, or cannot execute read-only database paths — `{"error":"…"}` |
|
| 403 | Not authorized, or cannot execute read-only database paths — `{"error":"…"}` |
|
||||||
| 404 | Applet not found — `{"error":"…"}` |
|
| 404 | Applet not found — `{"error":"…"}` |
|
||||||
| 500 | The applet threw during execution — `{"error":"…"}` |
|
| 500 | Sandbox worker harness failure — `{"error":"…"}` |
|
||||||
| 504 | The applet exceeded the execution timeout and was terminated — `{"error":"…"}` |
|
| 504 | The applet exceeded the execution timeout and was terminated — `{"error":"…"}` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ function captureResponseBody(res) {
|
|||||||
res.json = (payload) => {
|
res.json = (payload) => {
|
||||||
let out = payload;
|
let out = payload;
|
||||||
if (res.statusCode >= 500 && payload && typeof payload === 'object' && 'error' in payload) {
|
if (res.statusCode >= 500 && payload && typeof payload === 'object' && 'error' in payload) {
|
||||||
|
if (!res.locals?.error && typeof payload.error === 'string') {
|
||||||
|
res.locals = res.locals || {};
|
||||||
|
res.locals.error = new Error(payload.error);
|
||||||
|
}
|
||||||
out = { ...payload, error: 'Internal server error' };
|
out = { ...payload, error: 'Internal server error' };
|
||||||
}
|
}
|
||||||
body = out;
|
body = out;
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ function appletExecErrorStatus(error) {
|
|||||||
if (message.includes('is not a file')) return 400;
|
if (message.includes('is not a file')) return 400;
|
||||||
if (message.includes('Applet metadata') || message.includes('Applet input schema') || message.includes('Applet output schema')) return 400;
|
if (message.includes('Applet metadata') || message.includes('Applet input schema') || message.includes('Applet output schema')) return 400;
|
||||||
if (message.includes('Sandbox exceeded')) return 504;
|
if (message.includes('Sandbox exceeded')) return 504;
|
||||||
return 500;
|
if (message.includes('Sandbox worker did not report a result payload')) return 500;
|
||||||
|
return 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
@@ -163,7 +164,7 @@ export function register(app, basePath = '') {
|
|||||||
* truncationNote:
|
* truncationNote:
|
||||||
* type: string
|
* type: string
|
||||||
* 400:
|
* 400:
|
||||||
* description: No company selected, invalid path, not a .applet.js file, invalid input, or invalid applet metadata
|
* description: No company selected, invalid path, not a .applet.js file, invalid input, invalid applet metadata, or applet runtime error
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
@@ -187,7 +188,7 @@ export function register(app, basePath = '') {
|
|||||||
* schema:
|
* schema:
|
||||||
* $ref: '#/components/schemas/Error'
|
* $ref: '#/components/schemas/Error'
|
||||||
* 500:
|
* 500:
|
||||||
* description: The applet threw during execution
|
* description: Sandbox worker harness failure
|
||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
@@ -241,6 +242,7 @@ export function register(app, basePath = '') {
|
|||||||
return res.status(404).json({ error: 'File not found' });
|
return res.status(404).json({ error: 'File not found' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
res.locals.error = error;
|
||||||
const status = vfsFileErrorStatus(error);
|
const status = vfsFileErrorStatus(error);
|
||||||
if (status === 500) console.error('Execute vfs applet failed:', error);
|
if (status === 500) console.error('Execute vfs applet failed:', error);
|
||||||
return res.status(status).json({ error: error.message });
|
return res.status(status).json({ error: error.message });
|
||||||
@@ -258,6 +260,7 @@ export function register(app, basePath = '') {
|
|||||||
emit('vfs', { companyId: selected.companyId });
|
emit('vfs', { companyId: selected.companyId });
|
||||||
return res.json(result);
|
return res.json(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
res.locals.error = error;
|
||||||
const status = appletExecErrorStatus(error);
|
const status = appletExecErrorStatus(error);
|
||||||
if (status === 500) console.error('Execute vfs applet failed:', error);
|
if (status === 500) console.error('Execute vfs applet failed:', error);
|
||||||
return res.status(status).json({ error: error.message });
|
return res.status(status).json({ error: error.message });
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// @applet-input-schema {"type":"object","properties":{"sku":{"type":"string","title":"Article SKU","default":"","description":"Exact SKU to inspect. Leave empty for a single-row manifest summary."}}}
|
// @applet-input-schema {"type":"object","properties":{"sku":{"type":"string","title":"Article SKU","description":"Exact SKU to inspect (e.g. \"42000009\")."}},"required":["sku"]}
|
||||||
// @applet-output-schema key:string;value:string
|
// @applet-output-schema key:string;value:string
|
||||||
//
|
//
|
||||||
// Article lookup — the raw `GET /article/{sku}` payload as a key/value sheet.
|
// Article lookup — the raw `GET /article/{sku}` payload as a key/value sheet.
|
||||||
|
|||||||
Reference in New Issue
Block a user