From bf50b47bb505de700253a61cffd33b0ade9ba9be Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 25 Sep 2018 22:54:57 -0400 Subject: [PATCH] deprecate onerror - fixes #1745 --- src/compile/index.ts | 26 ++++++++++++++------------ src/compile/wrapModule.ts | 5 ++--- src/index.ts | 28 +++++++++++++++++----------- src/interfaces.ts | 2 +- src/utils/deprecate.ts | 8 ++++++++ test/parser/index.js | 2 ++ 6 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 src/utils/deprecate.ts diff --git a/src/compile/index.ts b/src/compile/index.ts index 239d09d2de..e5a78379ea 100644 --- a/src/compile/index.ts +++ b/src/compile/index.ts @@ -5,19 +5,16 @@ import renderDOM from './render-dom/index'; import renderSSR from './render-ssr/index'; import { CompileOptions, Warning, Ast } from '../interfaces'; import Component from './Component'; +import deprecate from '../utils/deprecate'; function normalize_options(options: CompileOptions): CompileOptions { let normalized = assign({ generate: 'dom', dev: false }, options); - const { onwarn, onerror } = normalized; + const { onwarn } = normalized; normalized.onwarn = onwarn ? (warning: Warning) => onwarn(warning, default_onwarn) : default_onwarn; - normalized.onerror = onerror - ? (error: Error) => onerror(error, default_onerror) - : default_onerror; - return normalized; } @@ -29,10 +26,6 @@ function default_onwarn({ start, message }: Warning) { } } -function default_onerror(error: Error) { - throw error; -} - function validate_options(options: CompileOptions, stats: Stats) { const { name, filename } = options; @@ -52,7 +45,17 @@ function validate_options(options: CompileOptions, stats: Stats) { } } -export default function compile(source: string, options: CompileOptions) { +export default function compile(source: string, options: CompileOptions = {}) { + const onerror = options.onerror || (err => { + throw err; + }); + + if (options.onerror) { + // TODO remove in v3 + deprecate(`Instead of using options.onerror, wrap svelte.compile in a try-catch block`); + delete options.onerror; + } + options = normalize_options(options); const stats = new Stats({ @@ -88,7 +91,6 @@ export default function compile(source: string, options: CompileOptions) { return renderDOM(component, options); } catch (err) { - options.onerror(err); - return; + onerror(err); } } \ No newline at end of file diff --git a/src/compile/wrapModule.ts b/src/compile/wrapModule.ts index 65b63c2077..0ae5a6edf8 100644 --- a/src/compile/wrapModule.ts +++ b/src/compile/wrapModule.ts @@ -276,7 +276,7 @@ function getCompatibilityStatements(dependencies: Dependency[]) { } function getGlobals(dependencies: Dependency[], options: CompileOptions) { - const { globals, onerror, onwarn } = options; + const { globals, onwarn } = options; const globalFn = getGlobalFn(globals); return dependencies.map(d => { @@ -284,10 +284,9 @@ function getGlobals(dependencies: Dependency[], options: CompileOptions) { if (!name) { if (d.name.startsWith('__import')) { - const error = new Error( + throw new Error( `Could not determine name for imported module '${d.source}' – use options.globals` ); - onerror(error); } else { const warning = { code: `options-missing-globals`, diff --git a/src/index.ts b/src/index.ts index 6c1949e472..b58fc2b837 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,24 +1,30 @@ import compile from './compile/index'; import { CompileOptions } from './interfaces'; +import deprecate from './utils/deprecate'; export function create(source: string, options: CompileOptions = {}) { - options.format = 'eval'; - - const compiled = compile(source, options); + const onerror = options.onerror || (err => { + throw err; + }); - if (!compiled || !compiled.js.code) { - return; + if (options.onerror) { + // TODO remove in v3 + deprecate(`Instead of using options.onerror, wrap svelte.create in a try-catch block`); + delete options.onerror; } + options.format = 'eval'; + try { - return (new Function(`return ${compiled.js.code}`))(); - } catch (err) { - if (options.onerror) { - options.onerror(err); + const compiled = compile(source, options); + + if (!compiled || !compiled.js.code) { return; - } else { - throw err; } + + return (new Function(`return ${compiled.js.code}`))(); + } catch (err) { + onerror(err); } } diff --git a/src/interfaces.ts b/src/interfaces.ts index 8bc8ed0b3f..b637a727bb 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -60,10 +60,10 @@ export interface CompileOptions { preserveComments?: boolean | false; - onerror?: (error: Error) => void; onwarn?: (warning: Warning) => void; // to remove in v3 + onerror?: (error: Error) => void; skipIntroByDefault?: boolean; nestedTransitions?: boolean; } diff --git a/src/utils/deprecate.ts b/src/utils/deprecate.ts new file mode 100644 index 0000000000..2ffbb36e59 --- /dev/null +++ b/src/utils/deprecate.ts @@ -0,0 +1,8 @@ +const seen = new Set(); + +export default function deprecate(message: string, code = message) { + if (seen.has(code)) return; + seen.add(code); + + console.warn(`[svelte] DEPRECATION: ${message}`); +} \ No newline at end of file diff --git a/test/parser/index.js b/test/parser/index.js index 7a87fc51b1..276cedfcab 100644 --- a/test/parser/index.js +++ b/test/parser/index.js @@ -48,6 +48,7 @@ describe('parse', () => { }); }); + // TODO remove in v3 it('handles errors with options.onerror', () => { let errored = false; @@ -61,6 +62,7 @@ describe('parse', () => { assert.ok(errored); }); + // TODO remove in v3 it('throws without options.onerror', () => { assert.throws(() => { svelte.compile(`

unclosed`);