mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
feature(user-menu) improve error handling
This commit is contained in:
parent
b8592d35c0
commit
64e6b8387a
5 changed files with 109 additions and 14 deletions
|
|
@ -7,10 +7,13 @@ require('../../../css/user-menu.css');
|
|||
const currify = require('currify/legacy');
|
||||
const wraptile = require('wraptile/legacy');
|
||||
const {promisify} = require('es6-promisify');
|
||||
const fullstore = require('fullstore/legacy');
|
||||
const load = require('load.js');
|
||||
const createElement = require('@cloudcmd/create-element');
|
||||
const tryCatch = require('try-catch');
|
||||
const tryToCatch = require('try-to-catch/legacy');
|
||||
const parse = require('./parse-error');
|
||||
const {codeFrameColumns} = require('@babel/code-frame');
|
||||
|
||||
const Images = require('../../dom/images');
|
||||
const Dialog = require('../../dom/dialog');
|
||||
|
|
@ -18,6 +21,7 @@ const getUserMenu = require('./get-user-menu');
|
|||
const navigate = require('./navigate');
|
||||
|
||||
const loadCSS = promisify(load.css);
|
||||
const sourceStore = fullstore();
|
||||
|
||||
const Name = 'UserMenu';
|
||||
CloudCmd[Name] = module.exports;
|
||||
|
|
@ -45,12 +49,15 @@ async function show() {
|
|||
|
||||
const {dirPath} = CurrentInfo;
|
||||
const res = await fetch(`${CloudCmd.prefix}/api/v1/user-menu?dir=${dirPath}`);
|
||||
const [error, userMenu] = tryCatch(getUserMenu, await res.text());
|
||||
const source = await res.text();
|
||||
const [error, userMenu] = tryCatch(getUserMenu, source);
|
||||
|
||||
Images.hide();
|
||||
|
||||
if (error)
|
||||
return Dialog.alert(`User menu error: ${error.message}`);
|
||||
return Dialog.alert(getCodeFrame({error, source}));
|
||||
|
||||
sourceStore(source);
|
||||
|
||||
const options = Object
|
||||
.keys(userMenu)
|
||||
|
|
@ -132,18 +139,41 @@ const onKeyDown = currify(async (keys, options, userMenu, e) => {
|
|||
const runUserMenu = async (value, options, userMenu) => {
|
||||
hide();
|
||||
|
||||
const [e] = await tryToCatch(userMenu[value], {
|
||||
const [error] = await tryToCatch(userMenu[value], {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
tryToCatch,
|
||||
});
|
||||
|
||||
if (!e)
|
||||
if (!error)
|
||||
return;
|
||||
|
||||
if (e.name === 'Error')
|
||||
return Dialog.alert(e.message);
|
||||
|
||||
return Dialog.alert(e.stack);
|
||||
const source = sourceStore();
|
||||
return Dialog.alert(getCodeFrame({
|
||||
error,
|
||||
source,
|
||||
}));
|
||||
};
|
||||
|
||||
function getCodeFrame({error, source}) {
|
||||
if (error.code === 'frame')
|
||||
return error.message;
|
||||
|
||||
const [line, column] = parse(error);
|
||||
const start = {
|
||||
line,
|
||||
column,
|
||||
};
|
||||
|
||||
const location = {
|
||||
start,
|
||||
};
|
||||
|
||||
const frame = codeFrameColumns(source, location, {
|
||||
message: error.message,
|
||||
highlightCode: false,
|
||||
});
|
||||
|
||||
return `<pre>${frame}</pre>`;
|
||||
}
|
||||
|
||||
|
|
|
|||
29
client/modules/user-menu/parse-error.js
Normal file
29
client/modules/user-menu/parse-error.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
const isNumber = (a) => typeof a === 'number';
|
||||
|
||||
module.exports = (error) => {
|
||||
const {
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
} = error;
|
||||
|
||||
if (isNumber(lineNumber) && isNumber(columnNumber))
|
||||
return [
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
];
|
||||
|
||||
const before = error.stack.indexOf('>');
|
||||
const str = error.stack.slice(before + 1);
|
||||
const after = str.indexOf(')');
|
||||
const newStr = str.slice(1, after);
|
||||
|
||||
const [line, column] = newStr.split(':');
|
||||
|
||||
return [
|
||||
Number(line),
|
||||
Number(column),
|
||||
];
|
||||
};
|
||||
|
||||
32
client/modules/user-menu/parse-error.spec.js
Normal file
32
client/modules/user-menu/parse-error.spec.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('supertape');
|
||||
const parseError = require('./parse-error');
|
||||
|
||||
test('user-menu: parse-error', (t) => {
|
||||
const result = parseError({
|
||||
lineNumber: 1,
|
||||
columnNumber: 2,
|
||||
});
|
||||
|
||||
const expected = [1, 2];
|
||||
|
||||
t.deepEqual(result, expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('user-menu: parse-error', (t) => {
|
||||
const stack = `
|
||||
ReferenceError: s is not defined
|
||||
at eval (eval at module.exports (get-user-menu.js:NaN), <anonymous>:1:2)
|
||||
at module.exports (get-user-menu.js:6)
|
||||
at tryCatch (VM12611 try-catch.js:7)
|
||||
at AsyncFunction.show (index.js:67)
|
||||
`;
|
||||
|
||||
const result = parseError({stack});
|
||||
const expected = [1, 2];
|
||||
|
||||
t.deepEqual(result, expected);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -162,6 +162,7 @@
|
|||
"writejson": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@cloudcmd/clipboard": "^1.0.2",
|
||||
|
|
|
|||
|
|
@ -72,13 +72,16 @@ async function onGET({req, res, menuName}) {
|
|||
if (parseError)
|
||||
return res
|
||||
.type('js')
|
||||
.send(`
|
||||
throw Error(\`<pre>path: ${menuPath}\n\n${codeframe({
|
||||
error: parseError,
|
||||
source,
|
||||
highlightCode: false,
|
||||
})}
|
||||
.send(`const e = Error(\`<pre>path: ${menuPath}\n\n${codeframe({
|
||||
error: parseError,
|
||||
source,
|
||||
highlightCode: false,
|
||||
})}
|
||||
</pre>\`);
|
||||
|
||||
e.code = 'frame';
|
||||
|
||||
throw e;
|
||||
`);
|
||||
|
||||
res
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue