Next.js Discord

Discord Forum

Server Actions - Rough Edges and Error Handling

Answered
Polar bear posted this in #help-forum
Open in Discord
Polar bearOP
Hey Next folks! :blob_wave:

I'm lead engineer on a Next 15.2 app and I'm doing what I can to make use of server actions but hitting some rough edges and need some input from experienced folks.

Here are some rough edges that I am running into:

- Server Action Failures - When using useActionState and let's say there's a network error(spotty internet, etc) my nextJS app is throwing a 500 error. I know I can create an error boundary but that's not the problem. The problem is that I want to notify a user: "Fetch failed due to network error" but this isn't straight forward because I don't have access to the Response.
- WAF use case - There's a waf that sits between our client and web server that will occasionally send a 405 request to recaptcha.
- How do you get access the server action response so that I can notify the user or do something like recaptcha test?
- Server Action Rate Limiting - Let's say I have a Resend Email Verifcation button and I want to rate limit this specific functionality for my sendVerificationEmail() action. Right now, this sends a POST request to /signin because that's the route where the action is called.
- I understand that we have the Next-Action header but the question is: How do I rate limit for a specific action?
- Server Action API HTTP Requests - Let's say that I want to have an endpoint that my legacy server needs to access. However, let's say that this is a Server Action endpoint and needs the next headers to access. How are you handling cases where another service needs to access a Server Action endpoint? Are you just creating both a server action + API route handler?
- That feels like double the work if I'm being honest. I'm struggling to see the real value of server actions if it opts out of HTTP altogether

Ok thanks for reading! These issues seem pretty fundamental to how the web works so I'm a bit frustrated.

Would love to hear how people are solving these! 🙏
Answered by joulev
Failures:
Errors in server actions are treated as if your server handler crashed, indicating a bug in your code. If you want to return an error message to the user, return it instead of throwing an error in your action

Rate limiting:
Usually you rate limit all requests to your server which would include the server actions as well. If you want a pattern to filter the server actions, look for POST requests with the next-action header

But in your case (send verification email), just implement the rate limiting in your action function content itself.

HTTP requests:
Server actions are not meant to be used by anything except the nextjs frontend. If you have another service wanting to access the same data, make http routes for that service. Up to you whether you want to retain the action or discard it in favour of using the http routes everywhere (in doing so you will opt out of [some features](https://nextjs-forum.com/post/1396477715091165265#message-1397164831337091083) only server actions have that ordinary http routes don’t have)
View full answer

4 Replies

@Polar bear Hey Next folks! <:blob_wave:753870952873590814> I'm lead engineer on a Next 15.2 app and I'm doing what I can to make use of server actions but hitting some rough edges and need some input from experienced folks. Here are some rough edges that I am running into: - **Server Action Failures** - When using `useActionState` and let's say there's a network error(spotty internet, etc) my nextJS app is throwing a 500 error. I know I can create an error boundary but that's not the problem. The problem is that I want to notify a user: "Fetch failed due to network error" but this isn't straight forward because I don't have access to the Response. - WAF use case - There's a waf that sits between our client and web server that will occasionally send a 405 request to recaptcha. - **How do you get access the server action response so that I can notify the user or do something like recaptcha test?** - **Server Action Rate Limiting** - Let's say I have a `Resend Email Verifcation` button and I want to rate limit this specific functionality for my `sendVerificationEmail()` action. Right now, this sends a POST request to `/signin` because that's the route where the action is called. - I understand that we have the `Next-Action` header but the question is: **How do I rate limit for a specific action?** - **Server Action API HTTP Requests** - Let's say that I want to have an endpoint that my legacy server needs to access. However, let's say that this is a Server Action endpoint and needs the next headers to access. **How are you handling cases where another service needs to access a Server Action endpoint?** Are you just creating both a server action + API route handler? - That feels like double the work if I'm being honest. I'm struggling to see the real value of server actions if it opts out of HTTP altogether Ok thanks for reading! These issues seem pretty fundamental to how the web works so I'm a bit frustrated. Would love to hear how people are solving these! 🙏
Failures:
Errors in server actions are treated as if your server handler crashed, indicating a bug in your code. If you want to return an error message to the user, return it instead of throwing an error in your action

Rate limiting:
Usually you rate limit all requests to your server which would include the server actions as well. If you want a pattern to filter the server actions, look for POST requests with the next-action header

But in your case (send verification email), just implement the rate limiting in your action function content itself.

HTTP requests:
Server actions are not meant to be used by anything except the nextjs frontend. If you have another service wanting to access the same data, make http routes for that service. Up to you whether you want to retain the action or discard it in favour of using the http routes everywhere (in doing so you will opt out of [some features](https://nextjs-forum.com/post/1396477715091165265#message-1397164831337091083) only server actions have that ordinary http routes don’t have)
Answer
Polar bearOP
Hey @joulev that is good feedback! Thanks for your reply 🙏

Re: Failures - In my case, the action is never called because the http request itself fails. How are you handling that? Both for spotty networks and my waf that 405's the action is never reached or times out. For example, load your app, turn off your internet connection and do the action. The failure is pretty clunky.

Re: Rate limiting - Good call. I guess I have to create some sort of Server Action wrapper that can rate limit so I don't have to do it for all actions. This is something I would expect to be handled by middleware but with actions it looks like it's not possible. Appreciate the idea!

And yep, hear you on the HTTP. I guess I'm still struggling to understand the value of server actions over API endpoints when these basic issues require quite a few additions in complexity to manage.
Polar bearOP
Yeah, I can see that it's a big issue for React if the request itself fails. IMO that's a huge miss because requests fail all the time for various reasons like I mentioned. Not having access the to request itself is super limiting because we need to give proper messaging and be able to handle different error cases.

I don't mind rendering the Error Boundary, but it doesn't help in my case because I need to do different things based on the failure. In an HTTP client for example, you can configure the error cases but with Server Actions you're SOL. Not ideal.

Middleware: I will consider rate limiting all POST requests with Next-Action header but it's probably better to decorate the actions instead so that you can configure per action.

Thanks for the help!