lud

lud

Should Elixir get a new "bad return" exception?

Hello,

When writing libraries it is often useful to define behaviours for library users to implement.
In general, those behaviour callbacks must return a specific type, like {:reply, term, term} or {:ok, term}.

Callbacks should be properly documented and then user-implemented, so it is generally fine to exit or raise if the return value does not adhere to the spec.

In Erlang, this is done by throwing an error with {:bad_return_value, retval}. For instance:

defmodule GS do
  def init(_), do: :foo
end

GenServer.start_link(GS, [])

In that case the error will be formatted as bad return value: :foo by the Elixir Exception module, but it does not tell what did not behave properly.

This is a general problem not related to processes. In libraries you can find code like this:

case user_mod.some_callback("hello") do
  {:ok, v} -> {:ok, do_stuff(v)}
  {:error, _} = err -> err
  other -> exit({:bad_return_value, other})
end

I use this pattern a lot. But the stacktrace will not contain user_mod.some_callback, which is a problem.

You can find occurences in OTP code where the bad return tuple includes the MFA that misbehaved, and it is formatted as MyApp.Application.start(:normal, []) returned a bad value: :foo though I cannot find where this is formatted (currently testing on OTP 27.3.

Erlang processes have some kind of helpful output:

-module(foo).
-export([init/1]).
init([]) -> foo.

Calling that module:

gen_server:start_link(foo, [], []).

Gives the “initial call” information in the crash report:

=CRASH REPORT==== 19-Nov-2025::09:32:46.515514 ===
  crasher:
    initial call: foo:init/1
    pid: <0.96.0>
    registered_name: []
    exception exit: {bad_return_value,foo}
      in function  gen_server:init_it/6 (gen_server.erl, line 2222)

This is for processes but I’m not sure anything standard exists for generic functional code.

How do you handle this case in your libraries or behaviours that you expect your coworkers to implement correctly?

Do you think that a ReturnError exception could be helpful ? (not fan of the name but if follows the pattern of ArgumentError).

So we could use it like that:

case user_mod.some_callback("hello") do
  {:ok, v} -> {:ok, do_stuff(v)}
  {:error, _} = err -> err
  other -> raise ReturnError, module: user_mod, function: :some_callback, value: other
end

And/Or what do you think of a special case in the exception module that would treat {:bad_return_value, {{m,f,a}, term} when is_atom(m) and is_atom(f) and is_list(a) in a special way? (Not sure if backwards compatible though).

Thank you :slight_smile:

Where Next?

Popular in Discussions Top

lud
Hello, I just extracted the boilerplate management code that I used to work with in previous years: It is yet another generic input d...
New
christopheradams
I was recently asked to step up and become the maintainer for the Elixir Style Guide. It was, I believe, the first, and is now the most p...
New
New
fredwu
Hey folks, Just wanted to share my journey and experiences so far. Preface: I’ve been using Elixir for about 10 years now, so relatively...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
michallepicki
Hello! To save some time when switching projects or development machines, I glued together an asdf plugin that uses Erlang precompiled b...
New
bartblast
I recently started a discussion about reactive patterns in Hologram, but I realized I need to step back and design the composability arch...
New
kusokuzeshiki
I tried to generate pages with claude code and fluxon ui. I ask to claude code to generate real world page samples, the results are thes...
New
chrisliaw
Hi, I’m wondering is it my thinking process or this is the norm among the Elixir developer for the use of Struct and accessor functions ...
New
AstonJ
Inspired by Andrew’s post in another thread about types: If the main benefit of static typing is to catch errors, and most people think...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; someth...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement