Error in backend call

Strategies to return the backend errors

Last update: Dec 13, 2022

About this feature

When you are willing to manipulate or aggregate data, KrakenD’s default policy regarding errors and status codes is to hide from the client any backend details, except when you use the no-op encoding. The philosophy behind this is that clients have to be decoupled from their underlying services.

You can override the default policy of returning backend error details with different strategies:

  • Errors entirely handled by the backend (default strategy for no-op ): Show the HTTP status codes, headers, and body as returned by the backend (maximum one). You cannot manipulate data (except with plugins). Use no-op encoding.
  • Graceful degradation of the response (default strategy for non- no-op ): HTTP status codes are essentially 200 or 500, regardless of the backend(s) status codes. The body is built, merged, and manipulated from the working backends.
  • Include the backend errors in a new key. Same as above, but it shows the errors in a new key in the body—ideal for debugging multiple backends. Use return_error_details .
  • Forward the HTTP status code of a single backend. Sets an empty body when there are errors (obfuscation), but preserves the HTTP status codes of the backend. Use return_error_code .
  • Forward the HTTP status code and error body. No obfuscation. Forwards the error body and the status code of a single backend. Use return_error_code and return_error_msg together.
  • Show an interpretation but not the error body. Semi-obfuscation. The client sees an interpretation of the gateway like invalid status code, or context deadline exceeded but does not see the actual error delivered by the backend. The status code is always 200 or 500. Use return_error_msg . The flag is also compatible with no-op .

The different combinations are exemplified below.

Include the backend errors in a new key

If you prefer revealing error details to the client, you can show them in the gateway response. To achieve this, enable the return_error_details option in the backend configuration, and all errors will appear in the desired key.

Place the following configuration inside the backend configuration:

The return_error_details option sets an alias for this backend. When a backend fails, you’ll find an object named error_ + its backend_alias containing the detailed errors of the backend. If there are no errors, the key won’t exist.

An error example is:

All status are 200


The following configuration sets an endpoint with two backends that return its errors in two different keys:

Let’s say your backend_b has failed, but your backend_a worked just fine. The client’s response could look like this:

Forward the HTTP status code of a single backend

When you have one backend only and use an encoding different than no-op , you can choose to return the original HTTP status code to the client.

The gateway obfuscates the HTTP status codes of the backend by default for many reasons, including security and consistency. Still, if you prefer using the HTTP status code of the backend instead, you can enable the return_error_code flag.

The body of the error will be empty unless you complement it with the return_error_msg at the router configuration (see below):

Place the following configuration in the configuration:

Notice that the return_error_code and the return_error_details are mutually exclusive. You can use one or the other but not both. If you declare them together, the gateway will use only return_error_details .

Show an interpretation but not the error body

When you want to show the interpretation of the error but not the error of the backend, use the router option return_error_msg as follows:

Unresolved issues?

The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.

Читайте также:  Error unable to connect sql server

The Ultra-High performance Open Source API Gateway

KrakenD helps application developers release features quickly by eliminating all the complexities of SOA architectures while offering a unique performance.


Blazor Best Practices: Handling Errors

Errors are likely to occur, the question is how to handle them. Let’s take a look at best practices in handling them in your Blazor app.

Sooner or later, something is bound to go wrong in your Blazor app.

Be it an unexpected input, an edge case you didn’t preempt, or your web host taking your DB down for maintenance. Errors are likely to occur, the question is how to handle them.

There are a number of factors here, including:

  • How best to handle errors, so users aren’t left staring at a broken screen
  • How to diagnose and fix the problem when something does go wrong
  • Tactics you can use to make sure you’re aware of problems in production
  • Steps you can take to avoid or handle predictable errors

If you’re building Blazor web applications, you have a few options for tackling these challenges. Let’s take a look.

Errors During Development

The first place to catch errors is when you’re building your Blazor app. You’ll see slightly different errors depending on which hosting model you’re using (Server or WASM).

Blazor Server Errors During Development

If your Blazor Server app runs into a problem during development, you’re likely to see a message directing you to the browser console for more details.

The console will show you some more details, but if you really want to dig into the problem you’ll want to head over to your server to see more detailed errors.

If you’re running locally using the built-in ASP.NET web server, you’ve most likely got a terminal window open somewhere that looks a bit like this:

If you’re using Visual Studio you’ll also find this information reported in the Output > Debug window.

It’s fair to say there’s quite a bit of noise in this window! But if you scroll up to the first reported error you’ll usually find some details which can help track down the problem.

In this case its reporting a System Exception thrown on line 48 of FetchData.razor.

Sure enough, there’s our problem.


Blazor WASM Errors During Development

You’ll see something similar in your Blazor WASM app, albeit with slightly different wording.

Because the Blazor components are running in the browser you’ll automatically see more detailed/directly useful errors in the browser console.

In this case, the error is to be found at Index.razor, line 15.

Keeping the Lights On, Using Error Boundaries

If your Blazor Server app throws an error (see above), it effectively blocks your users from continuing, until they reload the app.

Blazor WASM is a little more forgiving and will let you dismiss the error and carry on.

Either way, though, you probably want to provide some more friendly and/or helpful information to your users when something goes wrong.

One way to achieve this is via error boundaries. You can wrap a part of your app in an error boundary, providing a handy way to catch and handle exceptions without bringing your entire application to its knees.

Take this example, where we have a page which renders a ProductDetails component, plus the standard Counter component.

Here’s how that ProductDetails component looks:

If we run this and click the button we’ll get that standard error bar we saw earlier and, in the case of Blazor Server, our app will end up in a “broken” state, requiring a reload to get back up and running.

To make this experience better for our users we can wrap the ProductDetails component in an ErrorBoundary .

With this in place, when we click the button, the exception still occurs but is handled, and the default UI for an error boundary is shown (in the same place as the component which has thrown the error).

Читайте также:  Service information system error

The good news is this keeps our app operational, and limits the exception to that one part of the UI. In this example we can still navigate to other pages and/or interact with the counter widget on this page, even in Blazor Server (where this would usually have put the circuit into a broken state and blocked the user from continuing).

By default, the ErrorBoundary component will render a div with the blazor-error-boundary CSS class when an error occurs.

You can override this and provide your own custom UI by defining an ErrorContent property.

If you want to dig further into error boundaries, check out this helpful post on Working With Unhandled Exceptions by Dave Brock.

Anticipate and Handle Errors

Everything we’ve talked about so far is in the context of unhandled exceptions.

If you choose to handle an exception, you can of course apply whichever logic you deem fit (the user need never know!). So one strategy is to anticipate and handle errors using a standard C# try/catch approach.

For example, in our ProductDetails example, we could try to fetch product details and handle any errors that might occur.

In practice, you probably don’t want to wrap everything in try/catch blocks and you can always use error boundaries to catch the errors instead.

But, if you have specific exceptions you want to handle, then the humble try/catch is a good option to have.

Retry Network Requests

We tend to assume that networks are reliable, and that a call to a backend API will always work, but in practice transient issues can occur when interacting with servers, and servers can become temporarily unavailable (especially when deployments are being pushed out, or tweaks made to the network which hosts the server).

For these reasons, it pays to assume that your network calls will sometimes fail, especially if you’re building a Blazor WASM app where most of your backend logic lives in a backend Web API.

You could take the brute force approach of manually wrapping every backend call in a try/catch , but this adds a lot of noise to your application and still leaves you facing the question of what to do when a network call does fail.

Instead, for these kinds of transient errors I prefer to use Polly in my Blazor apps.

Polly is an open-source library for defining retry policies and it works nicely with HttpClient to handle transient network failures.

First we need to add a reference to the NuGet package:

Then, in our Blazor WASM app we need to tweak Program.cs to use IHttpClientBuilder to register a HttpClient, and specify a retry policy for failed requests.


In this case, should an exception occur when we make a HTTP call, Polly will retry the call twice, once after 1 second, and again after 5. At that point, if the backend call is still throwing exceptions, the exception will be thrown as normal and our app will react accordingly.

Finally we just need to tell our WASM app to use this Default HttpClient when it requests an instance of HttpClient .

This is to maintain backwards compatibility. The WASM app will now use our “Default” HttpClient , complete with retry policy, whenever we inject HttpClient into a component.

Diagnose and Fix Errors in Production

When errors occur in production, they can be tricky to pin down; the key is to have enough information to try and understand/fix the problem.

This is where ASP.NET’s built-in logging mechanisms are really useful.

When you run your app (in development or production), you’ve probably noticed all those messages showing up in the console (like the one we explored earlier when we encountered an exception during development).

Читайте также:  Run time error 339 component mscomctl ocx or one

ASP.NET relies on something called ILogger to log information, warnings and errors to the console by default.

We can also lean on that in production to get detailed error logs when something goes wrong.

The implementation details vary here, depending on your hosting infrastructure and you can choose to store logs in a number of places.

The default logging destinations for Blazor Server are:

  • Console
  • Debug
  • EventSource
  • EventLog (in WIndows)

Blazor WASM, as it runs in the users browser, doesn’t have access to the client’s file system, or network.

Therefore, if you’re logging from Blazor WASM, you’re more limited in terms of where you can send logs, but your app is also likely to be interacting with a backend API which can record its own logs.

With both Server and WASM you can send logs to other destinations via third-party libraries (typically installed via NuGet), such as Elmah, Sentry and Serilog, to name a few.

Alternatively, you can go further and plug your app into a third-party Application Performance Management service, such as Azure Application Insights and RayGun, which will often give you much more detailed information about exactly what went wrong, and what else was happening at the time.

However you choose to store them, you’ll want to consider what “level” of log to store.

If you take a look at your appsettings.json file in your Blazor Server app (or backend Web API if you’re using Blazor WASM), you’ll likely see this configuration:

This indicates that, in production, the default logging behavior is to record logs at the level of “Information” (and above), except for errors from ASP.NET Core which will only be logged if they are at “Warning” level or above.

If you’re using Blazor WASM you can control this level via Program.cs.

As well as capturing existing logs, you might want to log additional information from your components. You can do this by injecting an instance of ILogger , then invoking its LogX methods (where X is the level).


Alerts When Something Goes Wrong

Finally, if you do choose to lean on a third-party library for error logging, you may find they can also raise notifications (for example, via email) when something goes wrong.

If your app is broken, you probably want to know about it! Alert emails are a useful option to make sure you know something’s up.

Tools like Elmah and Serilog, and APMs like RayGun and Application Insights can handle this for you, and also make sure you don’t get flooded with emails when the same error starts recurring more than once.

In Conclusion

Errors are an inevitable part of web development. Blazor, and ASP.NET Core in general, provides several mechanisms to help you handle them.

Error boundaries can contain unhandled exceptions and keep your Blazor Server app running even though one component has failed.

Whether you’re using Blazor WASM or Server, knowing what’s gone wrong in Production or Development is key; use logs to make sure you can dig into the details of any errors which occur.

Consider third-party tools to surface logs and send alert emails when problems occur, and implement a simple retry policy for network requests (so your app can withstand transient network issues).

Jon Hilton

Jon spends his days building applications using Microsoft technologies (plus, whisper it quietly, a little bit of JavaScript) and his spare time helping developers level up their skills and knowledge via his blog, courses and books. He’s especially passionate about enabling developers to build better web applications by mastering the tools available to them. Follow him on Twitter here.


Оцените статью