Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# [Unreleased]

## Enhancements

* Align the `Solid.UndefinedFilterError` message with `Solid.UndefinedVariableError` - include line number

## Bug fixes

* Return `{:error, errors}` tuple when both strict_filters and strict_variables are enforced while rendering a template
* Use correct variable name in the `Solid.UndefinedVariableError` message

# 1.0.1 (2025-07-04)

## Bug fixes
Expand Down
6 changes: 5 additions & 1 deletion lib/solid/argument.ex
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ defmodule Solid.Argument do
{:error, {:not_found, key}, context} ->
context =
if strict_variables do
Context.put_errors(context, %UndefinedVariableError{variable: key, loc: arg.loc})
Context.put_errors(context, %UndefinedVariableError{
variable: key,
original_name: arg.original_name,
loc: arg.loc
})
else
context
end
Expand Down
6 changes: 5 additions & 1 deletion lib/solid/undefined_filter_error.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ defmodule Solid.UndefinedFilterError do
defexception [:filter, :loc]

@impl true
def message(exception), do: "Undefined filter #{exception.filter}"
def message(exception) do
line = exception.loc.line
reason = "Undefined filter #{exception.filter}"
"#{line}: #{reason}"
end
end
4 changes: 2 additions & 2 deletions lib/solid/undefined_variable_error.ex
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
defmodule Solid.UndefinedVariableError do
@type t :: %__MODULE__{}
defexception [:variable, :loc]
defexception [:variable, :original_name, :loc]

@impl true
def message(exception) do
line = exception.loc.line
reason = "Undefined variable #{exception.variable}"
reason = "Undefined variable #{exception.original_name}"
"#{line}: #{reason}"
end
end
15 changes: 11 additions & 4 deletions test/solid/argument_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,10 @@ defmodule Solid.ArgumentTest do
arg = %Variable{original_name: "key[1]", loc: @loc, identifier: "key", accesses: accesses}
context = %Solid.Context{vars: %{"key" => "a string"}}
assert {:ok, nil, context} = Argument.get(arg, context, [], strict_variables: true)
assert context.errors == [%UndefinedVariableError{variable: ["key", 1], loc: @loc}]

assert context.errors == [
%UndefinedVariableError{variable: ["key", 1], original_name: "key[1]", loc: @loc}
]
end

test "array access and nested" do
Expand Down Expand Up @@ -376,7 +379,9 @@ defmodule Solid.ArgumentTest do
assert {:ok, 456, context} =
Argument.get(arg, context, filters, strict_variables: true)

assert context.errors == [%UndefinedVariableError{variable: ["key"], loc: @loc}]
assert context.errors == [
%UndefinedVariableError{variable: ["key"], original_name: "key", loc: @loc}
]
end

test "missing filter strict_filters" do
Expand Down Expand Up @@ -445,7 +450,7 @@ defmodule Solid.ArgumentTest do

assert context.errors == [
%Solid.UndefinedFilterError{filter: "unknown", loc: @loc},
%UndefinedVariableError{variable: ["key"], loc: @loc}
%UndefinedVariableError{variable: ["key"], original_name: "key", loc: @loc}
]
end

Expand Down Expand Up @@ -523,7 +528,9 @@ defmodule Solid.ArgumentTest do
strict_variables: true
)

assert context.errors == [%UndefinedVariableError{variable: ["name"], loc: @loc}]
assert context.errors == [
%UndefinedVariableError{variable: ["name"], original_name: "name", loc: @loc}
]
end
end
end
44 changes: 44 additions & 0 deletions test/solid_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,12 @@ defmodule SolidTest do
assert error == [
%Solid.UndefinedVariableError{
variable: ["var1"],
original_name: "var1",
loc: %Solid.Parser.Loc{line: 1, column: 5}
},
%Solid.UndefinedVariableError{
variable: ["var2"],
original_name: "var2",
loc: %Solid.Parser.Loc{line: 1, column: 16}
}
]
Expand Down Expand Up @@ -254,16 +256,19 @@ defmodule SolidTest do
assert error == [
%Solid.UndefinedVariableError{
variable: ["var1"],
original_name: "var1",
loc: %Solid.Parser.Loc{line: 1, column: 5}
},
%Solid.UndefinedVariableError{
variable: ["var2"],
original_name: "var2",
loc: %Solid.Parser.Loc{line: 1, column: 16}
},
# FIXME this should somehow point out which file?
# Check how liquid does this
%Solid.UndefinedVariableError{
variable: ["var3"],
original_name: "var3",
loc: %Solid.Parser.Loc{line: 1, column: 4}
}
]
Expand Down Expand Up @@ -296,6 +301,7 @@ defmodule SolidTest do
assert error == [
%Solid.UndefinedVariableError{
variable: ["var1"],
original_name: "var1",
loc: %Solid.Parser.Loc{line: 1, column: 5}
},
%Solid.UndefinedFilterError{
Expand All @@ -304,9 +310,47 @@ defmodule SolidTest do
},
%Solid.UndefinedVariableError{
variable: ["var2"],
original_name: "var2",
loc: %Solid.Parser.Loc{line: 1, column: 38}
}
]
end

test "undefined variable error message with multiple variables" do
template =
"{{ var1 }}\n{{ event.name }}\n{{ user.properties['name'] }}\n"

{:error, [first_error, second_error, third_error], _partial_result} =
template
|> Solid.parse!()
|> Solid.render(%{}, strict_variables: true, file_system: {TestFileSystem, nil})

assert String.contains?(Solid.UndefinedVariableError.message(first_error), "var1")

assert String.contains?(
Solid.UndefinedVariableError.message(second_error),
"event.name"
)

assert String.contains?(
Solid.UndefinedVariableError.message(third_error),
"user.properties['name']"
)
end

test "undefined filter error message with line number" do
template = "{{ var1 | not_a_filter }}"

assert_raise Solid.RenderError,
"1 error(s) found while rendering\n1: Undefined filter not_a_filter",
fn ->
template
|> Solid.parse!()
|> Solid.render!(%{"var1" => "value"},
strict_filters: true,
file_system: {TestFileSystem, nil}
)
end
end
end
end