Should I throw an unhandled when a custom Exception handler middleware? - asp.net-core-3.1

I have a custom middleware where I catch and log every exception, the part where I catch an unhandled exception looks like this:
catch (Exception exception)
{
this.logger.LogError(exception);
await context.Response.WriteAsync("Unhandled").ConfigureAwait(false);
}
But I'm wondering if besides logging I should throw, every blog I have seen just write the response but never throw, I dont know if I'm leaveing my API in a bad state and should throw so the load balancer creates a new container or is it OK to keep runing the same instance.

Related

Vertx not able to handle internal code error to client automatically

I have a verticle which accepts REST request, get data from other verticle through event bus and respond back to client.
vertx.exceptionHandler(event -> logger.error("Vertx exception ", event));
router.get("/api/v1/:param").handler(this::routerHandler);
public void routerHandler(RoutingContext rc) {
vertx.eventBus().request("data", param,
result -> {
if (result.succeeded()) {
logger.info("Request handled successfully");
// intentionally creating exception body() will return String
JsonObject jsonObject = (JsonObject) result.result().body();
rc.response().end(jsonObject)
}else{
logger.error("Request failed");
}
}
When a exception is raised it is printed in exception handler that I setup in vertx instance but after that the vertx is not reporting back the exception immediately to client instead it waits for timeout(30 secs) to occur.
I tried attaching error handler to router object and failure handler to route object but nothing helps to report the exception immediately to client. I know I can have a try catch and report the error in catch block. But I want know if there is any other way to handle this like Servlet or Spring MVC reports back to client even though the exception is not handled in code.
router.errorHandler(500,routingContext -> {
System.out.println(routingContext.failed());
routingContext.response().end("Exception ");
});
router.route().handler(BodyHandler.create()).failureHandler(routingContext -> {
Uncaught exceptions are reported to the context exceptionHandler. By default it prints the exception to the console.
You can configure it but you will not get a reference to the corresponding HTTP request anyway (the exception may come from different things).
Most problems like this are usually found during unit/integration/acceptance testing.
And for the remainders you could set a timeout handler on your router definition to make sure the request is ended before the default 30 seconds.
If you don't want to miss any uncaught exception, you should switch to the Vert.x Rxified API. When using RxJava, any exception thrown will be reported to the subscriber.

Spring Cloud Netflix: Remote service error handling with Feign

We are trying to put Spring Cloud Netflix into production environment. For now we encounter a problem about business logic error handling.
We're using Feign as HTTP REST client. Microservice A needs to invoke microservice B which is deployed in different JVM(or physical server). Microservice B may return some error message which belongs to business. For instance A needs to query order information from B but the order ID may not exist so B has to return the error message that tells A this order doesn't exist. A has to do if-else judgement from the return message to determine if there are erorrs, then code will be like the following snippet:
//remoteServiceA is an interface annotated with #FeignClient
resultA = remoteServiceA.foo();
if (resultA.hasError) {
} else {
}
resultB = remoteServiceB.foo();
if (resultB.hasError) {
} else {
}
// ... ...
There are so many if-else so that it's not graceful enough. What we want is remoteServieA.foo() can throw a self-defined runtime exception such as OrderNotExistException. Any idea to achieve this goal?
I've solved this problem.
I customized the ErrorDecoder component of Feign, in which I can throw my own exception according to the HTTP original response.
If you have Hystrix enabled, you should be able to wrap you serviceA.foo() in a try block and throw an exception in your remote service.
try {
serviceA.foo();
} catch(HystrixRuntimeException ex) {
throw new OrderNotExistException("Error message");
}
You still have to take in account that you can catch that kind of exception if your remote service doesn't answer, or if an other error happens. Maybe you can find information the exception about what happened and decide if you should throw your exception.
First thing that comes to my mind but work in one of my project.

Execution stops on Cookies.getCookie() call with no exceptions

I'm trying to read a Cookie value in my server side implementation class. After some debugging my code now looks like this:
logger.info("Initiating login");
String oracleDad;
try {
logger.info("inside try");
oracleDad = Cookies.getCookie("dad");
logger.info("Read dad from cookie: " + oracleDad);
} catch (Exception e) {
logger.error("Failed to read dad from cookie", e);
oracleDad = "gtmd";
}
When I execute this code my onFailure block is fired with a Status code Exception:
com.google.gwt.user.client.rpc.StatusCodeException: 500 The call
failed on the server; see server log for details
My logging output on the server looks like this:
[INFO] c.g.e.server.rpc.MyProjectImpl - Initiating login
[INFO] c.g.e.server.rpc.MyProjectImpl - inside try
How is it possible that neither logger, the INFO or the ERROR, fire after the Cookies.getCookie() call? I'd hoped that by adding the catch(Exception e) I'd get some error message explaining why the code fails. But execution just seems to stop silently.
I'm using com.google.gwt.user.client.Cookies. I thought client code can be run on the server, just not vice versa. Is that correct? Is there something else I'm missing?
I'm using com.google.gwt.user.client.Cookies. I thought client code can be run on the server, just not vice versa. Is that correct? Is there something else I'm missing?
No, that's not correct, yes there is something you are missing: Server code can't run on the client, and client code can't run on the server.
You are not getting an Exception. You are getting an Error or some other Throwable.
Try catching Throwable in your try/catch block, and you'll see that you are getting an error where the server JVM is unable to load the Cookies class, because something is wrong. The JVM thinks that a native library is missing (because it doesn't know what JSNI is or how to run it), so it throws an UnsatisfiedLinkError:
Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native.
In GWT, the Cookies class is meant to interact with the browser itself to see what cookies have been defined on the currently loaded page. To use cookies on a J2EE server, ask the HttpServletRequest object for the cookies it knows about, and their values.

How can I determine why onFailure is triggered in GWT-RPC?

I have a project that does 2 RPC calls and then saves the data that the user provided in tha datastore. The first RPC call works ok, but from the second I always recieve the onFailure() message. How can I determine why the onFailure() is triggered? I tried caught.getCause() but it doesn't return anything.
feedbackService.saveFeedback(email,studentName,usedTemplates,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
caught.getCause();
Window.alert("Failure!");
}
public void onSuccess(String result) {
Window.alert("Saved!");
}
});
Throwable instance is instance of an Exception. You can check if it is a custom Exception like this:
if (caught instanceOf CustomException){
or if you want to show the message of exception you can use the getMessage():
Window.alert("Failure: " + caught.getMessage());
GWT-rpc is not not easy to ebug if an error occurs.
The easiest part is th check if the Exception is part of StatusCodeException.
A Statuscode of 404 means, you are pointing to a wrong endpoint
0 means, that
The searver is unreachable
You don't have permissions to check, if the server is available (X-domain-request)
You can use the Chrome-Web-Inspector to bedug GWT-RPC
You should be able to see all calls from the browser to you backend.
The most common failures are because of serialization of object. You have to ensure, that all dtransferred object implement java.io.Serializable
Most of the time it will just be a server side exception being raised which fires the onFailure() method.
Try putting breakpoints on your server side. That should help you pinpoint what's going wrong.

Commit transaction then send email

In Java, let's say I have a transaction that once it is committed, I want to do another action, in this case, send an email.
Therefore,
try {
transaction.begin()
...
transaction.commit()
// point 1
Utility.sendEmail(...)
} catch (Exception e) {
transaction.rollback();
}
Is it possible for the thread to die/get killed at point 1 and not send an email ?
Any way to minimize this ? JTA + JMS perhaps, where the action of sending a message is part of a transaction ?
I'm investigating an issue and exploring whether this is possible. JVM is still alive (no OOM). I do not know the inner working of the app server so not sure if this is possible.
I can't say for sure if the rollback() in the catch clause has any effect if the commit() was OK and sendEmail() threw an exception. The quickest way to test this is to throw an exception from the sendEmail() method and see if the transaction was actually committed.
The way I would put it though, is to move the sendEmail() call away from your try block:
try {
transaction.begin()
...
transaction.commit()
} catch (Exception e) {
transaction.rollback();
}
try {
// point 1
Utility.sendEmail(...)
} catch (Exception e) {
// handle it
}
This way you can control what will happen if a rollback was made.
Also, I think that sending the email to a JMS queue is in most cases a good idea. Doing it like that will give your DB code permission to continue and supposedly give feedback to your user that everything went OK and the email will be sent whenever it fits the email controller's schedule. For example, there might be a connection issue with your email server and the email sending would hang for say 30 seconds before throwing an exception and your user would see this as a very long button click.