mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-18 05:50:43 -07:00
@@ -32,6 +32,8 @@ export interface LiquidOptions {
|
||||
strictFilters?: boolean;
|
||||
/** Whether or not to assert variable existence. If set to `false`, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause an exception. Defaults to `false`. */
|
||||
strictVariables?: boolean;
|
||||
/** Catch all errors instead of exit upon one. Please note that render errors won't be reached when parse fails. */
|
||||
catchAllErrors?: boolean;
|
||||
/** Hide scope variables from prototypes, useful when you're passing a not sanitized object into LiquidJS or need to hide prototypes from templates. */
|
||||
ownPropertyOnly?: boolean;
|
||||
/** Modifies the behavior of `strictVariables`. If set, a single undefined variable will *not* cause an exception in the context of the `if`/`elsif`/`unless` tag and the `default` filter. Instead, it will evaluate to `false` and `null`, respectively. Irrelevant if `strictVariables` is not set. Defaults to `false`. **/
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TopLevelToken, OutputToken } from '../tokens'
|
||||
import { Template, Output, HTML } from '../template'
|
||||
import { LiquidCache } from '../cache'
|
||||
import { FS, Loader, LookupType } from '../fs'
|
||||
import { LiquidError } from '../util/error'
|
||||
import { LiquidError, LiquidErrors } from '../util/error'
|
||||
import type { Liquid } from '../liquid'
|
||||
|
||||
export class Parser {
|
||||
@@ -31,9 +31,16 @@ export class Parser {
|
||||
public parseTokens (tokens: TopLevelToken[]) {
|
||||
let token
|
||||
const templates: Template[] = []
|
||||
const errors: LiquidError[] = []
|
||||
while ((token = tokens.shift())) {
|
||||
templates.push(this.parseToken(token, tokens))
|
||||
try {
|
||||
templates.push(this.parseToken(token, tokens))
|
||||
} catch (err) {
|
||||
if (this.liquid.options.catchAllErrors) errors.push(err as LiquidError)
|
||||
else throw err
|
||||
}
|
||||
}
|
||||
if (errors.length) throw new LiquidErrors(errors)
|
||||
return templates
|
||||
}
|
||||
public parseToken (token: TopLevelToken, remainTokens: TopLevelToken[]) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { toPromise, RenderError } from '../util'
|
||||
import { toPromise, RenderError, LiquidErrors, LiquidError } from '../util'
|
||||
import { Context } from '../context'
|
||||
import { Template } from '../template'
|
||||
import { Emitter, KeepingTypeEmitter, StreamedEmitter, SimpleEmitter } from '../emitters'
|
||||
@@ -14,6 +14,7 @@ export class Render {
|
||||
if (!emitter) {
|
||||
emitter = ctx.opts.keepOutputType ? new KeepingTypeEmitter() : new SimpleEmitter()
|
||||
}
|
||||
const errors = []
|
||||
for (const tpl of templates) {
|
||||
try {
|
||||
// if tpl.render supports emitter, it'll return empty `html`
|
||||
@@ -22,10 +23,14 @@ export class Render {
|
||||
html && emitter.write(html)
|
||||
if (emitter['break'] || emitter['continue']) break
|
||||
} catch (e) {
|
||||
const err = RenderError.is(e) ? e : new RenderError(e as Error, tpl)
|
||||
throw err
|
||||
const err = LiquidError.is(e) ? e : new RenderError(e as Error, tpl)
|
||||
if (ctx.opts.catchAllErrors) errors.push(err)
|
||||
else throw err
|
||||
}
|
||||
}
|
||||
if (errors.length) {
|
||||
throw new LiquidErrors(errors)
|
||||
}
|
||||
return emitter.buffer
|
||||
}
|
||||
}
|
||||
|
||||
+14
-1
@@ -8,7 +8,7 @@ import { Template } from '../template/template'
|
||||
const TRAIT = '__liquidClass__'
|
||||
|
||||
export abstract class LiquidError extends Error {
|
||||
private token!: Token
|
||||
public token!: Token
|
||||
public context = ''
|
||||
private originalError?: Error
|
||||
public constructor (err: Error | string, token: Token) {
|
||||
@@ -62,6 +62,19 @@ export class RenderError extends LiquidError {
|
||||
}
|
||||
}
|
||||
|
||||
export class LiquidErrors extends LiquidError {
|
||||
public constructor (public errors: RenderError[]) {
|
||||
super(errors[0], errors[0].token)
|
||||
this.name = 'LiquidErrors'
|
||||
const s = errors.length > 1 ? 's' : ''
|
||||
this.message = `${errors.length} error${s} found`
|
||||
super.update()
|
||||
}
|
||||
public static is (obj: any): obj is LiquidErrors {
|
||||
return obj.name === 'LiquidErrors'
|
||||
}
|
||||
}
|
||||
|
||||
export class UndefinedVariableError extends LiquidError {
|
||||
public constructor (err: Error, token: Token) {
|
||||
super(err, token)
|
||||
|
||||
Reference in New Issue
Block a user