Skip to content

Commit 387ca07

Browse files
committed
fixed error handling and try/except and dateTime
1 parent 968c9fb commit 387ca07

File tree

6 files changed

+90
-107
lines changed

6 files changed

+90
-107
lines changed

index.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<div class="container">
3030
<h4>JSPython development console</h4>
3131
<div id="editor">
32+
async def f1():
3233
errorFunc(1)
3334
errorFunc(3)
3435
errorFunc(6)
@@ -42,6 +43,7 @@ <h4>JSPython development console</h4>
4243

4344
return 1
4445
"""
46+
f1()
4547

4648
</div>
4749
<!--
@@ -111,7 +113,6 @@ <h4>JSPython development console</h4>
111113
try {
112114
const scope = {
113115
Math,
114-
dateTime: () => new Date(),
115116
errorFunc: p => {
116117

117118
if (p === 6) {
@@ -144,7 +145,7 @@ <h4>JSPython development console</h4>
144145
const data = typeof result === 'object' ? JSON.stringify(result, null, '\t') : String(result);
145146
resultEditor.getSession().setValue(data)
146147
} catch (err) {
147-
console.error(err);
148+
console.log('error', err);
148149
resultEditor.getSession().setValue(String(err.message))
149150
}
150151
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jspython-interpreter",
3-
"version": "2.0.10",
3+
"version": "2.0.11",
44
"description": "JSPython is a javascript implementation of Python language that runs within web browser or NodeJS environment",
55
"keywords": [
66
"python",

src/evaluator/evaluator.ts

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -80,46 +80,42 @@ export class Evaluator {
8080
return this.evalBlock(ast, blockContext);
8181
}
8282

83-
private invokeFunction(func: (...args: unknown[]) => unknown, fps: unknown[],
84-
loc: { moduleName: string, line: number, column: number }): unknown {
85-
try {
86-
if (fps.length === 0) { return func(); }
87-
if (fps.length === 1) { return func(fps[0]); }
88-
if (fps.length === 2) { return func(fps[0], fps[1]); }
89-
if (fps.length === 3) { return func(fps[0], fps[1], fps[2]); }
90-
if (fps.length === 4) {
91-
return func(fps[0], fps[1], fps[2], fps[3]);
92-
}
93-
if (fps.length === 5) {
94-
return func(fps[0], fps[1], fps[2], fps[3], fps[4]);
95-
}
83+
private invokeFunction(func: (...args: unknown[]) => unknown, fps: unknown[],
84+
loc: { moduleName: string, line: number, column: number }): unknown {
85+
86+
if (fps.length === 0) { return func(); }
87+
if (fps.length === 1) { return func(fps[0]); }
88+
if (fps.length === 2) { return func(fps[0], fps[1]); }
89+
if (fps.length === 3) { return func(fps[0], fps[1], fps[2]); }
90+
if (fps.length === 4) {
91+
return func(fps[0], fps[1], fps[2], fps[3]);
92+
}
93+
if (fps.length === 5) {
94+
return func(fps[0], fps[1], fps[2], fps[3], fps[4]);
95+
}
9696

97-
if (fps.length === 6) {
98-
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5]);
99-
}
97+
if (fps.length === 6) {
98+
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5]);
99+
}
100100

101-
if (fps.length === 7) {
102-
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6]);
103-
}
101+
if (fps.length === 7) {
102+
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6]);
103+
}
104104

105-
if (fps.length === 8) {
106-
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7]);
107-
}
105+
if (fps.length === 8) {
106+
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7]);
107+
}
108108

109-
if (fps.length === 9) {
110-
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8]);
111-
}
109+
if (fps.length === 9) {
110+
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8]);
111+
}
112112

113-
if (fps.length === 10) {
114-
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8], fps[9]);
115-
}
113+
if (fps.length === 10) {
114+
return func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8], fps[9]);
115+
}
116116

117-
if (fps.length > 10) {
118-
throw Error('Function has too many parameters. Current limitation is 10');
119-
}
120-
} catch (err) {
121-
var jspyError = new JspyError(loc?.moduleName || 'js-func-error.jspy', loc?.line || 0, loc?.column || 0, 'FuncCall', err.message || err);
122-
throw jspyError;
117+
if (fps.length > 10) {
118+
throw Error('Function has too many parameters. Current limitation is 10');
123119
}
124120

125121
}
@@ -161,23 +157,18 @@ export class Evaluator {
161157
}
162158
}
163159
catch (err) {
164-
if (err instanceof JspyEvalError) {
165-
// evaluation error should not be handled
166-
throw err;
167-
} else {
168-
const name = (err instanceof JspyError) ? (err as JspyError).name : typeof (err);
169-
const message = (err instanceof JspyError) ? (err as JspyError).message : err ?? err.message;
170-
const moduleName = (err instanceof JspyError) ? (err as JspyError).module : 0;
171-
const line = (err instanceof JspyError) ? (err as JspyError).line : 0;
172-
const column = (err instanceof JspyError) ? (err as JspyError).column : 0;
173-
174-
const firstExept = tryNode.exepts[0];
175-
const catchBody = firstExept.body;
176-
const ctx = blockContext;// cloneContext(blockContext);
177-
ctx.blockScope.set(firstExept.error?.alias || "error", { name, message, line, column, moduleName })
178-
this.evalBlock({ name: blockContext.moduleName, type: 'trycatch', body: catchBody } as AstBlock, ctx);
179-
ctx.blockScope.set(firstExept.error?.alias || "error", null)
180-
}
160+
const name = (err instanceof JspyError) ? (err as JspyError).name : typeof (err);
161+
const message = (err instanceof JspyError) ? (err as JspyError).message : err?.message ?? String(err);
162+
const moduleName = (err instanceof JspyError) ? (err as JspyError).module : 0;
163+
const line = (err instanceof JspyError) ? (err as JspyError).line : 0;
164+
const column = (err instanceof JspyError) ? (err as JspyError).column : 0;
165+
166+
const firstExept = tryNode.exepts[0];
167+
const catchBody = firstExept.body;
168+
const ctx = blockContext;// cloneContext(blockContext);
169+
ctx.blockScope.set(firstExept.error?.alias || "error", { name, message, line, column, moduleName })
170+
this.evalBlock({ name: blockContext.moduleName, type: 'trycatch', body: catchBody } as AstBlock, ctx);
171+
ctx.blockScope.set(firstExept.error?.alias || "error", null)
181172
}
182173
finally {
183174
if (tryNode.finallyBody?.length || 0 > 0) {

src/evaluator/evaluatorAsync.ts

Lines changed: 40 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -88,42 +88,38 @@ export class EvaluatorAsync {
8888
return await this.evalBlockAsync(ast, blockContext);
8989
}
9090

91-
private async invokeFunctionAsync(func: (...args: unknown[]) => unknown, fps: unknown[],
92-
loc?: { moduleName: string, line: number, column: number }): Promise<unknown> {
93-
try {
94-
if (fps.length === 0) { return await func(); }
95-
if (fps.length === 1) { return await func(fps[0]); }
96-
if (fps.length === 2) { return await func(fps[0], fps[1]); }
97-
if (fps.length === 3) { return await func(fps[0], fps[1], fps[2]); }
98-
if (fps.length === 4) {
99-
return await func(fps[0], fps[1], fps[2], fps[3]);
100-
}
101-
if (fps.length === 5) {
102-
return await func(fps[0], fps[1], fps[2], fps[3], fps[4]);
103-
}
91+
private async invokeFunctionAsync(func: (...args: unknown[]) => unknown, fps: unknown[],
92+
loc?: { moduleName: string, line: number, column: number }): Promise<unknown> {
93+
94+
if (fps.length === 0) { return await func(); }
95+
if (fps.length === 1) { return await func(fps[0]); }
96+
if (fps.length === 2) { return await func(fps[0], fps[1]); }
97+
if (fps.length === 3) { return await func(fps[0], fps[1], fps[2]); }
98+
if (fps.length === 4) {
99+
return await func(fps[0], fps[1], fps[2], fps[3]);
100+
}
101+
if (fps.length === 5) {
102+
return await func(fps[0], fps[1], fps[2], fps[3], fps[4]);
103+
}
104104

105-
if (fps.length === 6) {
106-
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5]);
107-
}
105+
if (fps.length === 6) {
106+
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5]);
107+
}
108108

109-
if (fps.length === 7) {
110-
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6]);
111-
}
109+
if (fps.length === 7) {
110+
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6]);
111+
}
112112

113-
if (fps.length === 8) {
114-
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7]);
115-
}
113+
if (fps.length === 8) {
114+
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7]);
115+
}
116116

117-
if (fps.length === 9) {
118-
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8]);
119-
}
117+
if (fps.length === 9) {
118+
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8]);
119+
}
120120

121-
if (fps.length === 10) {
122-
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8], fps[9]);
123-
}
124-
} catch (err) {
125-
var jspyError = new JspyError(loc?.moduleName || 'js-func-error.jspy', loc?.line || 0, loc?.column || 0, 'FuncCall', err.message || err);
126-
throw jspyError;
121+
if (fps.length === 10) {
122+
return await func(fps[0], fps[1], fps[2], fps[3], fps[4], fps[5], fps[6], fps[7], fps[8], fps[9]);
127123
}
128124

129125
if (fps.length > 10) {
@@ -168,23 +164,19 @@ export class EvaluatorAsync {
168164
}
169165
}
170166
catch (err) {
171-
if (err instanceof JspyEvalError) {
172-
// evaluation error should not be handled
173-
throw err;
174-
} else {
175-
const name = (err instanceof JspyError) ? (err as JspyError).name : typeof (err);
176-
const message = (err instanceof JspyError) ? (err as JspyError).message : err ?? err.message;
177-
const moduleName = (err instanceof JspyError) ? (err as JspyError).module : 0;
178-
const line = (err instanceof JspyError) ? (err as JspyError).line : 0;
179-
const column = (err instanceof JspyError) ? (err as JspyError).column : 0;
180-
181-
const firstExept = tryNode.exepts[0];
182-
const catchBody = firstExept.body;
183-
const ctx = blockContext;// cloneContext(blockContext);
184-
ctx.blockScope.set(firstExept.error?.alias || "error", { name, message, line, column, moduleName })
185-
await this.evalBlockAsync({ name: blockContext.moduleName, type: 'trycatch', body: catchBody } as AstBlock, ctx);
186-
ctx.blockScope.set(firstExept.error?.alias || "error", null);
187-
}
167+
// catches here all exceptions. Including JSPY Eval errors
168+
const name = (err instanceof JspyError) ? (err as JspyError).name : typeof (err);
169+
const message = (err instanceof JspyError) ? (err as JspyError).message : err?.message ?? String(err);
170+
const moduleName = (err instanceof JspyError) ? (err as JspyError).module : 0;
171+
const line = (err instanceof JspyError) ? (err as JspyError).line : 0;
172+
const column = (err instanceof JspyError) ? (err as JspyError).column : 0;
173+
174+
const firstExept = tryNode.exepts[0];
175+
const catchBody = firstExept.body;
176+
const ctx = blockContext;
177+
ctx.blockScope.set(firstExept.error?.alias || "error", { name, message, line, column, moduleName })
178+
await this.evalBlockAsync({ name: blockContext.moduleName, type: 'trycatch', body: catchBody } as AstBlock, ctx);
179+
ctx.blockScope.set(firstExept.error?.alias || "error", null);
188180
}
189181
finally {
190182
if (tryNode.finallyBody?.length || 0 > 0) {

src/initialScope.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import { parseDatetimeOrNull } from "./common/utils";
22

33
export const INITIAL_SCOPE = {
44
jsPython(): string {
5-
return [`JSPython v2.0.10`, "(c) 2021 FalconSoft Ltd. All rights reserved."].join('\n')
5+
return [`JSPython v2.0.11`, "(c) 2021 FalconSoft Ltd. All rights reserved."].join('\n')
66
},
7-
dateTime: (str: number | string | any = null) => (str && str.length)
8-
? parseDatetimeOrNull(str) || new Date() : new Date(),
7+
dateTime: (str: number | string | any = null) => parseDatetimeOrNull(str) || new Date(),
98
range: range,
109
print: (...args: any[]) => { console.log(...args); return args.length > 0 ? args[0] : null; },
1110
isNull: (v: any, defValue: any = null): boolean | any => defValue === null ? v === null : v || defValue,

src/parser/parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ export class Parser {
415415
throw new Error(`Tokens length can't empty.`)
416416
}
417417

418-
if (getTokenValue(tokens[tokens.length-1]) === ';') {
418+
if (getTokenValue(tokens[tokens.length - 1]) === ';') {
419419
throw new Error(`Unexpected symbol ';' in the end`)
420420
}
421421

@@ -578,7 +578,7 @@ export class Parser {
578578
const paramsNodes = this.createExpressionNode(paramsTokensSlice);
579579
return new BracketObjectAccessNode(name, paramsNodes, false, getTokenLoc(tokens[0]));
580580
}
581-
581+
582582
throw Error(`Undefined node '${getTokenValue(tokens[0])}'.`);
583583
}
584584
}

0 commit comments

Comments
 (0)