Listener-level error handler vs Container-level error handler in Spring Kafka - spring-kafka

With my team, we are trying to set up an error handling policy common to several microservices (for the majority of cases). My team and I are struggling to understand the difference between a listener-level error handler and a container-level error handler. What are the real implications behind this choice? Is it only the fact that the container error handler does not have access to the message?
The KafkaListenerErrorHandler allows a more fine grained exception handling, we can use on the content of the exception to define if it is retryable or not.
In the error handler containers it seems more complicated, before it was possible to provide a custom classifier but not anymore, we can only pass a classification map.
In the past we used to use the SeekToCurrentErrorHandler (now DefaultErrorHandler), which was recommended in the documentation. I saw another StackOverflow thread related to this topic but I can't quite make the connection with our questions. The documentation doesn't seem to address the implications of this choice.
Thank you very much.

The main use case for the listener-level error handler is for request/reply processing; it allows the error handler to send some other result to the sender to indicate the request wasn't processed. As you say, it also provides access to the spring-messaging converted Message<?> (possibly with a converted payload); e.g. for logging; it can re-throw the exception to invoke the container EH.
Regarding classification, that change was to allow classifications to be added and removed dynamically. If you prefer to have the old behavior (allowing a custom classifier) to be restored, please open an issue on GitHub.

Related

Accessing a thread un-safe COMobject in classic ASP

Trying to fix a problem in a classic ASP application, however I am inexperienced. Tried to find more info but was unable to.
The app instantiates a COM object for data retrieval which is not thread-safe, so the following instructions are added.
comObject=CreateObject("comServer.comObject")
returnValue=comObject.DoWork(.......)
...
comObject = Nothing
However, when processing two different http requests at the same time, the latter one seems to overwrite the first request, giving the first requester an error. It looks as if the comObject variable is shared between the requests.
How to instantiate the object in such a way that every separate request in IIS, gets it's own instance of the comObject?
Without knowing what the object does or how it does it, it's impossible to give specific advice. A general description will have to do:
The object is broken/buggy. It is the object's responsibility to handle the problem.
A COM object is supposed to handle all threading issues internally, or defer to COM STA apartments if it cannot do it, or doesn't want to (for those aspects that an STA can handle). This goes deep into the design of the object.
Regardless of COM Apartment choice, a DoWork(...) method with a semantic that precludes multiple separate COM objects in separate threads from handling simultaneous calls - is a seriously problematic design at best. A proper design would either include mechanisms to handle the conflict explicitly, or just hide the conflict from the calling code and handle the conflict internally.
Depending on the details of what DoWork() does, there might be ways to fix the object in such a way that the calls can succeed in parallel, or block each other so the calls are effectively serialized, or to cause the second call to throw a "You already called me" error. Again, which approach is more appropriate depends heavily on what the method does.
If you can't modify this broken component, your best option would be to write a COM wrapper that ensures serialization to the real object.
In any case, there is nothing reasonable you can do from the client (ASP VBScript) side.

Should I catch all my exceptions in the global.asax?

If I am just logging exception details in my web app, do I really need to put in exception handling logic for each tier? Why not just let them all bubble up the stack trace to the global.asax and log them there?
I would suggest against using any exception handling logic in any layer of your application unless:
The exception is not a fatal one, meaning that there is some action you can take to recover, or
The application should continue functioning and the exception should be "ignored." An example: when checking out at an online retailer you are sent a receipt via email. If that fails - but the other order processing stuff succeeds - the user should not be shown an error page. Here, we want the workflow to continue even though there is an exception. Most exceptions do not fall into this category.
Of course, exceptions - whether they are fatal or not or should be "ignored" or not - need to be logged and developers notified. This is best handled through an event handler for the Application.Error event. Yes, this can be done in Global.asax, but I think it's cleaner to use an HTTP Module-based approach, either Health Monitoring or ELMAH.
I've written an article on this topic that I'd like to recommend to you - Exception Handling Advice for ASP.NET Web Applications. Here is the article in summary:
My advice for handling exceptions in an ASP.NET application can be boiled down to the following guidelines:
(a) Create and use a meaningful custom error page.
(b) In general, do not catch exceptions. Let them bubble up to the ASP.NET runtime. Some cases where catching an exception makes sense include:
When there is a plausible way to recover from the exception by performing some alternative logic,
When a peripheral part of the application's workflow throws and exception and that exception should not derail the entire application, and
When you need to include additional information with the exception by throwing a new exception that has the original exception as its inner exception.
(c) Log all exceptions to some persistent store and use email (or some other medium) to notify developers when an exception occurs in production. Consider using ELMAH or ASP.NET's built-in Health Monitoring system to facilitate this process.
Exceptions should bubble up to whatever layer can handle them in a meaningful way, being aware of the Single Responsibility principle. For instance, your data layer should not be invested in logging.
The Application.Error event is a good place for catch-all error handling: that is, unexpected and/or fatal errors that require no special treatment beyond logging/alerting and redirecting to an error page.
If your web app makes use of the Microsoft AJAX extensions and partial postbacks, you'll need to handle exceptions in at least two places:
Global.asax
Your ScriptManager's OnAsyncPostBackError handler
For further information on OnAsyncPostBackError, check out:
http://msforge.net/blogs/janko/archive/2008/02/13/handling-exceptions-in-asp-net-ajax.aspx
http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.onasyncpostbackerror.aspx
I say that on global try to catch the error that you miss on the logic steps of your program and redirect them on an "error page", or a "not found page".
All other errors not necessary show the error on the user, and not need to send it to an error page.
For example, in page with 2 or more, different modules, if the one throw an error, just hide it, and show the rest. Similar try to catch errors when they happens and handle them the best non visual way to the user if this is possible, log them and correct them later.
Now this error that happens only on one module, you can see it on your log and correct it, but until you do that, user see something on your page and not a full error page.
Usually what I do is do a try...catch in the code, but instead of logging on the catch what I do is pass it on with a message stating where the error came from, etc. Then I use Elmah to catch all of the errors and log them.
That way you only have to deal with the logging in one area and satisfy the Single Responsiblity Principle, but you have more information available for debugging purposes. It can also be helpful when you get that data error that only seems to occur with 1 out of 500 users.

AS3 LocalConnection asyncError

I'm working on implementing communication between an Adobe AIR app and a browser Flash object, and the LocalConnection documentation mentions an asyncError as a potential event:
asyncError: Dispatched when an exception is thrown asynchronously — that is, from native asynchronous code.
However, that's the only documentation I can find on it. Does anyone know what this error actually means? I've searched around but couldn't find any reference -- most sample code I found does an addEventListener() for the asyncError but doesn't give any clue as to what it means or when it could occur (i.e. if it could occur when sending or when recieving).
The Adobe documentation page also lists potential events for each method, but asyncError isn't listed under any specific method, only for the general class.
Has anyone ever had an asyncError occur?
Thanks!
This error is also dispatched from NetConnection. In that case it's used as expected: to handle errors thrown asynchronously by the connection. In the handler for the NetConnection if you do something like:
trace(event.text);
You will get something back like:
Error #2095: flash.net.NetStream was unable to invoke callback onMetaData.
You can use the same technique to figure out why the LocalConnection is throwing this error and handle it according to the message.

How to return errors to view from controller not tied to a specific model property

Curious what the best practice is for returning errors to a view from a controller where the error isn't really a validation error, but more like "user not found" or "service timeout" type of errors. (in ASP.NET MVC2 framework)
I've been adding them to the ModelState's model errors, but that doesn't seem appropriate. (although easy to implement and maintain)
Example - A user tries to log in, and their credentials do not match a known user.
I believe you need to be slightly more clear with regards to what youre calling an error.
Exceptions (timed out, database error, etc.) should be handled using specific exception handlers (not least because you often don't want to show the error message to the end user).
In this scenario, look at overloading the OnException() method on the controller. (or having all your controllers inherit from a common ControllerBase which has that method overriden to avoid repetition)
You may also want to check the value of filterContext.HttpContext.IsCustomErrorEnabled when handling exceptions to determine whether to expose detailed exception information or to obfuscate it.
Remember that exceptions should be for exceptional circumstances - "normal" operation should never result in an exception
The other type of error you're mentioning is more like "Unable to process request due to business rules / invalid input" (or similar) in which case, adding error messages to the ViewModel seems appropriate. They may not be direct validation errors but they are most likely as a result of the user input
I've just researched this, and I think that for network-related errors and so on, which are bound to happen, it's OK to use TempData (but don't put the Exception inside but the exception message only, for security reasons).
http://forums.asp.net/p/1460169/3353779.aspx

ASP.NET Error Handling

In my asp.net applications, I've typically used the Application_Error global event handler to log the error and redirect the user to a user-friendly error page.
However, I have read about ELMAH and while that seems interesting, Application_Error seems like the simpler approach.
I've read other questions where people, including myself, have suggested one way or the other. What I'm wondering is if there is any significant benefit to using one over the other and why?
Elmah is a fantastic project and we use it for all of our ASP.NET applications. Not only does it log unhandled errors for you, it grabs the entire original page that the user saw, which contains a lot of detail for you.
It has email support, RSS feeds (both itemized and digest) and has an attractive console.
For 3 lines in config and a dll reference, I'd say that's a slam dunk.
I guess the main drawback of ELMAH is that it might be overkill for what you need. If it's logging and storing more info than you would in your own implementation, that's an unnecessary overhead in storage and processing. You also need to think about how you secure access to ELMAH's console since those exception details could contain juicy details of your app (that needn't be hard, but it's a worry that you didn't have before).
On the other hand, your own implementation will probably grow to log all that extra information once you decide that some stubborn bug requires it, and do you really care about shaving fractions of a second off the time that it takes for the error page to be displayed? Chances are you'll eventually end up building your own version of ELMAH, so why not just use ELMAH and save yourself the time.
I'd recommend that if you do want to write your own error logging rather than using ELMAH, you at least put it in a module rather than straight into Application_Error in global.asax. Just subscribe to the application's Error event in your module's Init method, and you can easily reuse your error handling code in another application with a line in web.config.
I also find it useful to handle any exception logging through ASP.NET's health monitoring. This makes it easy to control the type and level of logging in web.config, and also allows logging of exceptions that were handled in a try...catch without getting as far as Application_Error. Create a custom HandledExceptionEvent class that extends WebRequestErrorEvent, and you can create and raise those events in any catch block where you'd really like to know that the exception happened even though it was handled.

Resources