Skip to content

Commit

Permalink
Improve jinja2 error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
m-o-e committed Mar 26, 2024
1 parent 1464244 commit 40d855d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
9 changes: 9 additions & 0 deletions spec/envcat/cli/format/j2_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ describe Envcat::Cli do
}
end

it "fails cleanly on 'empty expression' template error" do
tpl = "{{}}"
expect_output(/^$/, /^Malformed template:/, tpl) { |o, e, i|
expect_raises(Exit, "3") {
Envcat::Cli.invoke(%w[-f j2], o, e, i)
}
}
end

it "fails if any referenced var is undefined" do
tpl = "{{FOO}} {{BAR}}"
expect_output(/^$/, /Undefined variable: BAR/, tpl) { |o, e, i|
Expand Down
2 changes: 1 addition & 1 deletion src/envcat/cli.cr
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ class Envcat::Cli
rescue ex : Format::UnknownFormatIdError
io_err.puts "Unknown format: #{ex.message}"
exit E_SYNTAX
rescue ex : Crinja::TemplateSyntaxError | Crinja::FeatureLibrary::UnknownFeatureError | Crinja::TypeError
rescue ex : Crinja::TemplateSyntaxError | Crinja::FeatureLibrary::UnknownFeatureError | Crinja::TypeError | Format::J2::RenderError
io_err.puts "Malformed template: #{ex.message}"
exit E_SYNTAX
rescue ex : ParseException
Expand Down
27 changes: 17 additions & 10 deletions src/envcat/format/j2.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ require "crinja"

# 🐒
class Crinja::Undefined
class_property strict = false # ameba:disable Style/QueryBoolMethods
class_property strict = false # ameba:disable Naming/QueryBoolMethods
class_property tagged = [] of String

def to_s(io)
Expand All @@ -24,6 +24,8 @@ module Envcat
class Format::J2 < Format::Formatter
class UndefinedVariableError < Exception; end

class RenderError < Exception; end

@@strict = true

def self.description : String
Expand All @@ -37,18 +39,23 @@ module Envcat
def write(env)
Envcat.claim_stdin! if @io_in == STDIN

Crinja::Undefined.strict = @@strict
begin
Crinja::Undefined.strict = @@strict

crinja = Crinja.new(Crinja::Config.new(keep_trailing_newline: true))
crinja = Crinja.new(Crinja::Config.new(keep_trailing_newline: true))

crinja.filters["split"] = Crinja.filter({on: nil}) { target.to_s.split(arguments["on"].to_s) }
crinja.filters["b64encode"] = Crinja.filter { Base64.strict_encode(target.to_s) }
crinja.filters["b64encode_urlsafe"] = Crinja.filter { Base64.urlsafe_encode(target.to_s) }
crinja.filters["b64decode"] = Crinja.filter { Base64.decode_string(target.to_s) }
crinja.filters["split"] = Crinja.filter({on: nil}) { target.to_s.split(arguments["on"].to_s) }
crinja.filters["b64encode"] = Crinja.filter { Base64.strict_encode(target.to_s) }
crinja.filters["b64encode_urlsafe"] = Crinja.filter { Base64.urlsafe_encode(target.to_s) }
crinja.filters["b64decode"] = Crinja.filter { Base64.decode_string(target.to_s) }

buf = IO::Memory.new(16384)
IO.copy(@io_in, buf)
crinja.from_string(buf.to_s).render(@io, env.as(Envcat::Env))
buf = IO::Memory.new(16384)
IO.copy(@io_in, buf)
crinja.from_string(buf.to_s).render(@io, env.as(Envcat::Env))
rescue ex
raise ex if ex.is_a? Format::J2::UndefinedVariableError
raise RenderError.new(ex.message)
end
end
end
end

0 comments on commit 40d855d

Please sign in to comment.