mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-14 05:14:28 -08:00
throw null
This commit is contained in:
@@ -170,7 +170,18 @@ export const find_node = (node, pred) => {
|
|||||||
export const find_error_origin_node = node =>
|
export const find_error_origin_node = node =>
|
||||||
find_node(
|
find_node(
|
||||||
node,
|
node,
|
||||||
n => n.result != null && !n.result.ok && n.result.error != null
|
n => n.result != null && !n.result.ok && (
|
||||||
|
n.result.error != null
|
||||||
|
||
|
||||||
|
// In case if throw null or throw undefined
|
||||||
|
n.type == 'throw'
|
||||||
|
||
|
||||||
|
// await can also throw null
|
||||||
|
n.type == 'unary' && n.operator == 'await'
|
||||||
|
// or function call throwing null or undefined
|
||||||
|
||
|
||||||
|
n.type == 'function_call'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Maps tree nodes, discarding mapped children, so maps only node contents, not
|
/* Maps tree nodes, discarding mapped children, so maps only node contents, not
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ export const set_location = (state, location) => set_cursor_position(
|
|||||||
|
|
||||||
const is_stackoverflow = node =>
|
const is_stackoverflow = node =>
|
||||||
// Chrome
|
// Chrome
|
||||||
node.error.message == 'Maximum call stack size exceeded'
|
node.error?.message == 'Maximum call stack size exceeded'
|
||||||
||
|
||
|
||||||
// Firefox
|
// Firefox
|
||||||
node.error.message == "too much recursion"
|
node.error?.message == "too much recursion"
|
||||||
|
|
||||||
export const calltree_node_loc = node => node.toplevel
|
export const calltree_node_loc = node => node.toplevel
|
||||||
? {module: node.module}
|
? {module: node.module}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export class CallTree {
|
|||||||
el('i', '',
|
el('i', '',
|
||||||
'toplevel: ' + (n.module == '' ? '*scratch*' : n.module),
|
'toplevel: ' + (n.module == '' ? '*scratch*' : n.module),
|
||||||
),
|
),
|
||||||
n.ok ? '' : el('span', 'call_header error', '\xa0', n.error.toString()),
|
n.ok ? '' : el('span', 'call_header error', '\xa0', stringify_for_header(n.error)),
|
||||||
)
|
)
|
||||||
: el('span',
|
: el('span',
|
||||||
'call_header '
|
'call_header '
|
||||||
@@ -135,7 +135,7 @@ export class CallTree {
|
|||||||
),
|
),
|
||||||
')' ,
|
')' ,
|
||||||
// TODO: show error message only where it was thrown, not every frame?
|
// TODO: show error message only where it was thrown, not every frame?
|
||||||
': ', (n.ok ? stringify_for_header(n.value) : n.error.toString())
|
': ', (n.ok ? stringify_for_header(n.value) : stringify_for_header(n.error))
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(n.children == null || !is_expanded)
|
(n.children == null || !is_expanded)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {exec, get_state} from '../index.js'
|
import {exec, get_state} from '../index.js'
|
||||||
import {ValueExplorer} from './value_explorer.js'
|
import {ValueExplorer, stringify_for_header} from './value_explorer.js'
|
||||||
import {el, stringify, fn_link} from './domutils.js'
|
import {el, stringify, fn_link} from './domutils.js'
|
||||||
import {FLAGS} from '../feature_flags.js'
|
import {FLAGS} from '../feature_flags.js'
|
||||||
|
|
||||||
@@ -244,7 +244,7 @@ export class Editor {
|
|||||||
|
|
||||||
exp.render(value)
|
exp.render(value)
|
||||||
} else {
|
} else {
|
||||||
content.appendChild(el('span', 'eval_error', error.toString()))
|
content.appendChild(el('span', 'eval_error', stringify_for_header(error)))
|
||||||
}
|
}
|
||||||
|
|
||||||
this.widget = {
|
this.widget = {
|
||||||
|
|||||||
22
test/test.js
22
test/test.js
@@ -456,6 +456,21 @@ export const tests = [
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
test('throw null', () => {
|
||||||
|
assert_code_error(`throw null`, null)
|
||||||
|
}),
|
||||||
|
|
||||||
|
test('throw null from function', () => {
|
||||||
|
const code = `
|
||||||
|
const throws = () => { throw null }
|
||||||
|
throws()
|
||||||
|
`
|
||||||
|
const s = test_initial_state(code)
|
||||||
|
const moved = COMMANDS.move_cursor(s, code.indexOf('throws()'))
|
||||||
|
assert_equal(moved.value_explorer.result.ok, false)
|
||||||
|
assert_equal(moved.value_explorer.result.error, null)
|
||||||
|
}),
|
||||||
|
|
||||||
test('new', () => {
|
test('new', () => {
|
||||||
assert_code_evals_to('new Error("test").message', 'test')
|
assert_code_evals_to('new Error("test").message', 'test')
|
||||||
}),
|
}),
|
||||||
@@ -2774,6 +2789,13 @@ const y = x()`
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
test('async/await promise rejected with null', async () => {
|
||||||
|
await assert_code_error_async(
|
||||||
|
`await Promise.reject()`,
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
|
||||||
test('async/await await rejected Promise returned from async', async () => {
|
test('async/await await rejected Promise returned from async', async () => {
|
||||||
await assert_code_error_async(
|
await assert_code_error_async(
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {parse, print_debug_node, load_modules} from '../src/parse_js.js'
|
import {print_debug_node, load_modules} from '../src/parse_js.js'
|
||||||
import {eval_tree, eval_frame} from '../src/eval.js'
|
|
||||||
import {active_frame, pp_calltree} from '../src/calltree.js'
|
import {active_frame, pp_calltree} from '../src/calltree.js'
|
||||||
import {COMMANDS} from '../src/cmd.js'
|
import {COMMANDS} from '../src/cmd.js'
|
||||||
|
|
||||||
@@ -17,21 +16,18 @@ export const parse_modules = (entry, modules) =>
|
|||||||
load_modules(entry, module_name => modules[module_name])
|
load_modules(entry, module_name => modules[module_name])
|
||||||
|
|
||||||
export const assert_code_evals_to = (codestring, expected) => {
|
export const assert_code_evals_to = (codestring, expected) => {
|
||||||
const parse_result = parse(codestring)
|
const s = test_initial_state(codestring)
|
||||||
assert_equal(parse_result.ok, true)
|
const frame = active_frame(s)
|
||||||
const tree = eval_tree(parse_result.node)
|
|
||||||
const frame = eval_frame(tree)
|
|
||||||
const result = frame.children.at(-1).result
|
const result = frame.children.at(-1).result
|
||||||
assert_equal({ok: result.ok, value: result.value}, {ok: true, value: expected})
|
assert_equal(result.ok, true)
|
||||||
|
assert_equal(result.value, expected)
|
||||||
return frame
|
return frame
|
||||||
}
|
}
|
||||||
|
|
||||||
export const assert_code_error = (codestring, error) => {
|
export const assert_code_error = (codestring, error) => {
|
||||||
const parse_result = parse(codestring)
|
const state = test_initial_state(codestring)
|
||||||
assert_equal(parse_result.ok, true)
|
const frame = active_frame(state)
|
||||||
const tree = eval_tree(parse_result.node)
|
const result = frame.children.at(-1).result
|
||||||
const frame = eval_frame(tree)
|
|
||||||
const result = frame.children[frame.children.length - 1].result
|
|
||||||
assert_equal(result.ok, false)
|
assert_equal(result.ok, false)
|
||||||
assert_equal(result.error, error)
|
assert_equal(result.error, error)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user