binarypaladin

binarypaladin

I’ve been trying to figure out how to handle the authorization layer of a Phoenix app I’m working on which has brought me full circle to something I’ve noticed about the Phoenix defaults since I first started tinkering with it:

The default get! functions in contexts raise an Ecto.NoResultsError which is caught and generally displayed as a 404.

In consideration for authorization, does it make sense to just raise some other sort of exception that’s caught somewhere higher up?

With that said, in reading around, I’m having a hard time understanding how the get! convention meshes with advice about exceptions being “exceptional.” Is a lack of a resource in a repo really exceptional? (And I am not being glib either, this is a serious question). This seems like a case of exception as flow control. Is this observation correct? And if it is, is this an acceptable convention in Elixir?

I found this question on StackOverflow and the accepted answer quotes José but doesn’t seem to provide the source. For reference:

In Elixir, this distinction is rather theoretical, but they matter in some languages like Ruby, where using errors/exceptions for control-flow is expensive because creating the exception object and backtrace is expensive.

Are exceptions as flow-control in Elixir acceptable and, more specifically, do they not incur the same sort of performance hit as Ruby?

Asking specifically since I used throw/catch quite a lot in Ruby. In this situation, I’m debating between some sort of :error/:ok pattern or just raising an exception.

Showing Posts 1 to 5

smathy

smathy

FWIW, performance doesn’t really figure into my reasoning for whether to use throw or raise (or any long jumping) for flow control (which I almost never do). The main reason is that it makes it harder to follow the flow of your code. The more of them you use, the more complex that chain is to unravel.

The pattern I’ve gotten into for authorization is essentially the same as Bodyguard uses. A with block in your controllers that starts with an authorization check, and the block contains the happy path, and the auth check returns an {:error, tuple} on error which becomes the return value of your controller action, and therefore falls through to your FallbackController.

It’s a very simple flow to understand, follow, customize, test, etc.

binarypaladin

binarypaladin OP

with is actually my go to right now. I absolutely love it. I caught another topic here where someone mentioned adding a fetch_* to his contexts.

I’m just trying to understand the design choices in Phoenix. One of the hardest things about adopting new languages and frameworks is the whole, “Am I doing this the ‘right way’?” syndrome.

On top of that, with frameworks it’s generally better to do with their conventions rather than against.

It’s just, if I adopt that pattern for authorization, it seems like having it for fetching would be ideal.

wmnnd

wmnnd

When you’re talking about authorization within the context of Phoenix/Plug pipelines, it’s quite straightforward to implement a plug that simply halts/redirects the processing of the current pipeline.

Here’s a super simple pattern I’ve been using for resource authorization lately:
https://github.com/pentacent/keila/blob/main/lib/keila_web/controllers/sender_controller.ex#L6
https://github.com/pentacent/keila/blob/main/lib/keila_web/controllers/sender_controller.ex#L100

smathy

smathy

Ok - so again - this is just my take (from over 25 years of working with a wide variety of frameworks, although my exposure to Elixir/Phoenix is fairly recent).

My take has always been that the whole get! missing ID being translated to a 404 convention was because in RESTful routes, the ID is part of the URL, and so a 404 makes sense. That URL/resource literally cannot be found on the server.

My take on why framework authors use exceptions (which a lot do) for this is because it really is exceptional. In normal usage, you really can’t get a URL that maps to a resource that doesn’t exist. Ie. if this happens it’s because someone is trying to get to something they shouldn’t by editing the URL directly, or because you have a bug in your URL generating code.

Summary, people aren’t using this mechanism for simple flow control. They’re using it because it really shouldn’t happen - which is an appropriate use of exceptions.

smathy

smathy

PS. Worth adding that some of that reasoning, re exceptional situations, could map to certain authorization use cases. If you just had a single user type, or maybe it’s an API where you’re tightly controlling the resources you’re directing users to. Ie. where no one would sharing URLs, no one innocently stumbling into a place they don’t have access to, etc. I can imagine exceptions making more sense in an app like that.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews