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

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New

Other Trending Topics Top

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
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews