#How to send an http error code from a server$ function?

17 messages · Page 1 of 1 (latest)

little mirage
#

Hello, I am trying to prevent unauthenticated users from running actions on a per-function basis. For that, I would like to send a 403 error code if the user is unauthenticated, but I am not sure how to do that.
Here is what my code looks like:

export const myFunc = server$(async function () {
  try {
    // Throws an error if the user is not logged-in
    const session = requireLogin(this);

    // server-side stuff

  } catch (error) {
    // How to send 403 here?
  }
});

I know that I could use middlewares, but if I understand correctly, they are set on a per-route basis, which is not granular enough for me. I am open to discussing it though.

Thank you!

quaint kindle
#

You have several alternatives:

  • middlewares in route index.tsx (run for a single route, doesn't run for server$ functions)
  • middlewares in route layout.tsx (run for the route and all its subroutes, doesn't run for server$ functions)
  • middlewares in a [email protected] (run for every route and every server$ functions)

Alternatively, if you don't want to secure all server$ functions and only have a few "private" server$ functions, you can throw an exception with an error code/message that you try/catch on a case per case basis.

little mirage
#

Thank you for the answer. I have indeed considered the three first alternatives, but I want only a few private functions.

I believe that it is not possible to throw something server-side, and catch it client-side. Do you mean that I should catch server-side and send an object describing the error? That would mean that I cannot leverage the http status code and should instead define my own error handling even-though the function sends 200, which seems to go against standards. I will do it if there is no other way, but I would prefer avoiding it.

crisp beacon
#

If you use your server$ functions directly in the middlewares that load the data on route, then you can catch the errors thrown and properly send an error code

#

within the component boundary, that is way after the headers sent so you cannot modify them on the fly

#

the best you can do is to show an error message where the component renders

little mirage
#

I see, thank you for the answer!
I am not sure I understand why I cannot modify the status when calling server$ from the client, since the call creates a new http request (it even returns 500 if an error is not caught inside the server call), but that is probably beyond my current understanding of Qwik-city.
I guess I will implement my own error handling, and ignore the http status code.

crisp beacon
#

You probably can do a redirect to the error page though

#

pretty much all action does go to the server, executes there unless you explicitly say otherwise

#

a global error popup would be pretty neat, but afaik that is not a feature yet

little mirage
#

Indeed, but I would rather display a popup that explains the error, rather than redirecting. My use case specifically regards client-server calls (due to user actions), and I would like to display a message showing what the user has done wrong.

crisp beacon
#

Yeah, I got pretty used to those with laravel livewire, although on production that is hidden as no user should see programmer errors 😄

#

I suspect the DX was not the major priority there, and overall you can use the <Resource /> anyway to render an error block in-place

little mirage
#

I do not mean programmer error, I mean if a user fills a form wrong for example, and for some reason it goes past client-side verifications, i would like to display a popup error with an explanation

#

Yes the Resource component is great for that. I still need to know what message to display in it though.

crisp beacon
#

you do get back the data you parse, so you can pass your response's stuff

little mirage
#

Yeah I guess I will format the response so that it can return an "error". I am just a bit disappointed that I am unable to leverage the standard API. Thank you!