From 74ae0abd4c58835da2e664f21b7fb29313233b90 Mon Sep 17 00:00:00 2001 From: Patrick Sinclair Date: Tue, 23 Jul 2024 11:06:40 +0100 Subject: [PATCH] Improve the error message when the wrong number of arguments are provided Currently when a user provides the wrong number of arguments, they receive a message saying `echo is not implemented.`. This message is confusing because it makes the user feel like they typed in the wrong function name, when in reality they just provided the wrong number of arguments. This is a first draft at a fix - feedback welcome! --- lib/expression/callbacks.ex | 13 +++++++++++++ lib/expression/v2/callbacks.ex | 13 +++++++++++++ test/expression_custom_callbacks_test.exs | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/expression/callbacks.ex b/lib/expression/callbacks.ex index 9d0bb1e..ca4d57d 100644 --- a/lib/expression/callbacks.ex +++ b/lib/expression/callbacks.ex @@ -93,12 +93,25 @@ defmodule Expression.Callbacks do function_exported?(Standard, vargs_function_name, 2) -> {:vargs, Standard, vargs_function_name, 2} + # Check if the wrong number of arguments was provided + wrong_arity_but_function_exists?(module, exact_function_name) -> + {:error, "wrong number of arguments to #{function_name}."} + + # Check if the wrong number of arguments was provided + wrong_arity_but_function_exists?(Standard, exact_function_name) -> + {:error, "wrong number of arguments to #{function_name}."} + # Otherwise fail true -> {:error, "#{function_name} is not implemented."} end end + defp wrong_arity_but_function_exists?(module, function_name) + when is_atom(module) and is_atom(function_name) do + Enum.any?(0..20, fn arity -> Kernel.function_exported?(module, function_name, arity) end) + end + defmacro __using__(_opts) do quote do import Expression.Callbacks.EvalHelpers diff --git a/lib/expression/v2/callbacks.ex b/lib/expression/v2/callbacks.ex index d826231..1ab3b5d 100644 --- a/lib/expression/v2/callbacks.ex +++ b/lib/expression/v2/callbacks.ex @@ -97,12 +97,25 @@ defmodule Expression.V2.Callbacks do function_exported?(Standard, vargs_function_name, 2) -> {:vargs, Standard, vargs_function_name} + # Check if the wrong number of arguments was provided + wrong_arity_but_function_exists?(module, exact_function_name) -> + {:error, "wrong number of arguments to #{function_name}."} + + # Check if the wrong number of arguments was provided + wrong_arity_but_function_exists?(Standard, exact_function_name) -> + {:error, "wrong number of arguments to #{function_name}."} + # Otherwise fail true -> {:error, "#{function_name} is not implemented."} end end + defp wrong_arity_but_function_exists?(module, function_name) + when is_atom(module) and is_atom(function_name) do + Enum.any?(0..20, fn arity -> Kernel.function_exported?(module, function_name, arity) end) + end + defmacro __using__(_opts) do quote do def callback(module \\ __MODULE__, context, function_name, args) diff --git a/test/expression_custom_callbacks_test.exs b/test/expression_custom_callbacks_test.exs index f29ee2f..b3fd640 100644 --- a/test/expression_custom_callbacks_test.exs +++ b/test/expression_custom_callbacks_test.exs @@ -44,7 +44,7 @@ defmodule ExpressionCustomCallbacksTest do end test "wrong arity functions" do - assert {:error, "echo is not implemented."} == + assert {:error, "wrong number of arguments to echo."} == Expression.Callbacks.implements( ExpressionCustomCallbacksTest.CustomCallback, "echo",