Failing test for onError handler.

Rather than _always_ adding a try/catch this adds a try/catch only when on_error is present. Doesn't currently work because apparently updates and initial renders go through different paths. Also because I need maintainer support to figure this out...
pull/3587/head
Chris Pfohl 6 years ago
parent 14a46a17d0
commit 1135336e88

@ -3,6 +3,7 @@ import './ambient';
export { export {
onMount, onMount,
onDestroy, onDestroy,
onError,
beforeUpdate, beforeUpdate,
afterUpdate, afterUpdate,
setContext, setContext,

@ -19,6 +19,7 @@ interface T$$ {
context: Map<any, any>; context: Map<any, any>;
on_mount: any[]; on_mount: any[];
on_destroy: any[]; on_destroy: any[];
on_error: any[];
} }
export function bind(component, name, callback) { export function bind(component, name, callback) {
@ -88,6 +89,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
// lifecycle // lifecycle
on_mount: [], on_mount: [],
on_error: [],
on_destroy: [], on_destroy: [],
before_update: [], before_update: [],
after_update: [], after_update: [],

@ -27,6 +27,10 @@ export function onDestroy(fn) {
get_current_component().$$.on_destroy.push(fn); get_current_component().$$.on_destroy.push(fn);
} }
export function onError(fn) {
get_current_component().$$.on_error.push(fn);
}
export function createEventDispatcher() { export function createEventDispatcher() {
const component = current_component; const component = current_component;

@ -71,6 +71,15 @@ export function flush() {
function update($$) { function update($$) {
if ($$.fragment) { if ($$.fragment) {
if ($$.on_error.length == 0) {
exec_update($$);
} else {
try_exec_update($$);
}
}
}
function exec_update($$) {
$$.update($$.dirty); $$.update($$.dirty);
run_all($$.before_update); run_all($$.before_update);
$$.fragment.p($$.dirty, $$.ctx); $$.fragment.p($$.dirty, $$.ctx);
@ -78,4 +87,19 @@ function update($$) {
$$.after_update.forEach(add_render_callback); $$.after_update.forEach(add_render_callback);
} }
function try_exec_update($$) {
try {
exec_update($$);
} catch (e) {
let handled = false;
for (let i = 0; i < $$.on_error.length; i += 1) {
const callback = $$.on_error[i];
const result = callback(e);
if (result !== false) {
handled = true;
}
}
if (!handled) throw e;
}
} }

@ -77,6 +77,7 @@ export function create_ssr_component(fn) {
// these will be immediately discarded // these will be immediately discarded
on_mount: [], on_mount: [],
on_error: [],
before_update: [], before_update: [],
after_update: [], after_update: [],
callbacks: blank_object() callbacks: blank_object()

@ -0,0 +1,7 @@
export default {
test({ assert, target }) {
const div = target.querySelector('div');
assert.equal('error', div.className);
}
};

@ -0,0 +1,16 @@
<script>
import { onError } from 'svelte';
let error;
onError(err => {
error = err;
});
function getWidget() {
throw new Error('Oops');
}
</script>
{#if error}
<div class='error'>{error.message}</div>
{:else}
<div class='success'>{getWidget()}</div>
{/if}
Loading…
Cancel
Save