Error handling with try catch (AGAIN) - error-handling

just a general question,
do you ALWAYS have to handle error?
i was just having this debate with one of my coworker where in his code I see a lot places where stuff are wrapped around a try statement and in the catch statement there is nothing.
I always thought it is a bad practice to not handling error or hide them from the user (except log them in the log file).
just want to know what other people thinks
thanks.

If you can't handle the exception, then don't catch it. It may be that someone further up the call stack can properly handle it, and congratulations, you've now prevented them from doing their job <golfclap/>.

The practice of catching an exception and then "silencing it" is EVIL! i think 99.99% of all SOers will agree on that one.
Here's a very nice article from CodeProject on exception handling best practices. Guess what one of the sections is devoted to?
The worst thing you can do is catch (Exception) and put an empty code block on it. Never do this.
Any exception handling article worth its salt will mention the exception swallowing concept, and not to do it, in some way.

Only a Sith deals in absolutes. Seriously, though, I can think of at least one instance we ran across just recently where it was desirable to just drop it and move on. We recently implemented an in-house click tracking solution that sends an async AJAX request to an MVC controller to be logged. We don't care if it does not get logged and we don't want our own logs filling up with error logs that we don't want. so why bother with the overhead of doing anything in the catch block. We considered adding code in the catch block to at least increment a counter when we got an error, but there was no business reason for it at this time.
It really comes down to whether you are doing it out of laziness or because there is actually a good reason not to.
I'll probably get flack for saying that as it is bad practice in general. Do I get points for bravery?

You have to handle the exception if there is something you can do with it
try
{
//CODE
}
catch
{
LogException();
//and/or
RollbackTransaction();
//and/or
ShowFriendlyMessageToUser();
//and/or
DoSomethingUsefullWithTheException();
throw; //This is optional
}
This make no sense, but I've seen it a lot
try
{
//CODE
}
catch
{
throw;
}
EDIT 1
And you need a very good argument to put something like this. And probably you'll get fired anyway :-p
try
{
//CODE
}
catch
{
//HIDE TO THE WORLD THAT THIS IS FAILING
}

Related

NServicesBus disable FLR for specific exceptions completely

I'm trying to disable retries for some specific exceptions completely.
I know that in my code - when I'm trying to handle message X and if the handler throw a "ZZZ" type exception, I'm sure there's no way any number of retries would help;
What I want to do is send that message directly to error queue immediately without any retries.
How can i do that ?
I know you've already accepted an answer, but since you are trying to circumvent the plumbing builtin for a very specific scenario, you could handle the message in a try/catch and either send the message directly to the error queue or let the FLR/SLR handle it.
Please note, this is not an ideal scenario. In most cases, it is actively discouraged to handle the error handling of messages and instead allow the infrastructure to manage it.
Here's a possible implementation:
public void Handle(SomeCommand message)
{
try
{
//Do thing that might throw exception
}
catch (SpecificException ex)
{
_bus.Send(new Address("errorQueue", "machine"), message);
}
catch (Exception ex)
{
throw ex;
}
}
EDIT I'm promoting Marcin's comment to be included in this answer so it isn't missed:
Please bear in mind that by using this approach without setting
appropriate message headers you will lose the ability to return these
failed messages to the source queue. Please take a look at this doco
for details: http://docs.particular.net/nservicebus/messaging/headers#retries-handling-headers. – Marcin
Hoppe
You can't for the first level retries, only for the second level retries. I personally wouldn't worry about it (I have something similar, where certain exceptions I know that it won't be fixed). There's generally no downside to letting them go in the FLR.

NServiceBus UnitOfWork to swallow certain exceptions and avoid message failure

I have an interesting use case where certain exception types mean "This message is no longer valid and should be ignored" but this code doesn't have any awareness of the Bus in order to call Bus.DoNotContinueDispatchingCurrentMessageToHandlers().
I loathe boilerplate code like try/catch blocks that need to be present in every single message handler. So I started implementing a UnitOfWork to handle and swallow the exception, but I can't find a way to tell the framework that "Yes, this code generated an exception, but forget about that and just complete the transaction."
Bus.DoNotContinueDispatchingCurrentMessageToHandlers() does not work. I tried having an ITransport injected and calling AbortHandlingCurrentMessage() but that caused the entire universe to blow up. Even stepping through the source code I seem to be at a loss.
Note that it very well may be that this is a horrible idea, because faking that there is no exception when there is in fact an exceptional case would cause the transaction to commit, causing who knows how many bad unknown side effects. So it would be preferable to have a method that still rolls back the transaction but discards the message. But I would be interested in a potential "Yes I know what I'm doing, commit the transaction regardless of the exception" option as well.
As of NServiceBus version 4.4 you can control this by injecting a behavior into our handler pipeline.
This let's you control which exceptions to mute.
class MyExceptionFilteringBehavior : IBehavior<HandlerInvocationContext>
{
public void Invoke(HandlerInvocationContext context, Action next)
{
try
{
//invoke the handler/rest of the pipeline
next();
}
//catch specific exceptions or
catch (Exception ex)
{
//modify this to your liking
if (ex.Message == "Lets filter on this text")
return;
throw;
}
}
There are several samples of how this works:
http://docs.particular.net/samples/pipeline/
That said I totally agree with Ramon that this trick should only be used if you can't change to design to avoid this.
A dirty solution would be having a unit of work test the exception, put the message id in a shared 'ignore' bag (concurrent dictionary in memory, db, what works for you) , let it fail so that everything is rolled back, in the retry have a generic message handler compare the message ID and let that call Bus.DoNotContinueDispatchingCurrentMessageToHandlers()
If you do not want to work with a unit of work then you could try to use the AppDomain.FirstChanceException.
I wouldn't advice any of these as good solution :-)
Why would you like to 'swallow' unhandled exceptions?
If you want to ignore an exception then you should catch these in the handler and then just return and log this.
What I'm more interested in is what about state? You maybe have already writen to a store. Shouldn't these writes be rolled back? If you swallow an exception the transaction commits.
It seems to me you are running in a kind of 'at least once delivery' environment. THen you need to store some kind of message id somewhere.
Or is it an action initiated by several actors based on a stale state? In that case you need to have first/last write wins construction that just ignores a command based on a stale item.
If you handl an event then swallowing a exception seems not correct. They usually say that you can ignore commands but that you always have to handle events.
Shouldn't this be part of validation? If you validate a command then you can decide to ignore it.

Is there a way to get the last thrown exception outside of a try/catch block?

Edit:
To all answerers and commenters: Please focus on providing the solution I request rather than offer ways to refactor it. The code provided below is a very condensed example for the sake of brevity. I've already stated below that this type of code exists in 20 or 30 places throughout the app and that I am choosing not to move/merge/refactor any of that code if a simpler solution exists.
Original Question:
First, here's brief run-down: We have an app that was developed by an offshore team. The purpose of this application is to run nightly maintenance on various database tables. It is a WinForms app, but it acts more like a console app as all it does is 1) execute a single method in Form1_Load and then 2) call End to shut down the program.
The problem is that the error email notification doesn't work, so I have been charged with the task of fixing it. Consider this code:
Try
'This inner Try/Catch is actually code in another method
Try
'Run some code here
Catch ex As Exception
'Errors are logged silently to text file here
End Try
Catch ex As Exception
'Code to email exception details is here
End Try
The problem is that an exception is thrown and handled in the inner Try/Catch. Because of this, there's no exception to be handled in the outer Try/Catch, hence why no email notification is being sent.
Someone might say to just add Throw ex in the inner Catch, but keep in mind that there are about 20 or 30 places in the code where exceptions are handled like this. The decision I am making is to just get it working for now and not undergo that kind of development effort. Therefore, I seek a way to somehow acquire the last exception thrown by the application. This way, I can add a Finally block to the outer Try/Catch and do something like this:
Finally
If Not Application.GetLastException() is Nothing Then
SendErrorEmail(Application.GetLastException())
End If
End Try
So if I understand this correctly, your application catches all exceptions and logs them silently to a file.
You want to change the behavior so that when the program ends you get the last exception thrown, if any, and send an email with that exception detail. But the last exception thrown isn't stored anywhere.
And you want to change this behavior without modifying the code that handles the exceptions.
That can't be done. How do you expect to change the program's behavior without changing the program's behavior? What you ask is impossible. (And, no, not even Yoda would be able to pull this particular X-wing out of the swamp.)
There is no runtime property that automatically saves the last exception thrown.
You will have to make some modification to the code that catches the exceptions. You say that the code takes this general format:
Try
'This inner Try/Catch is actually code in another method
Try
'Run some code here
Catch ex As Exception
'Errors are logged silently to text file here
End Try
Catch ex As Exception
'Code to email exception details is here
End Try
I take it that the problem is in the inner Catch block. Seems to me that if there's common code to log the errors to a text file, that code should be in a separate method. If it is, then modify that method to save the last exception in a property that can be accessed by your GetLastException method. If there isn't a common method that handles the exception logging then you'll have to make the change at every place.
The commenters are correct: A general "catch all exceptions" is almost always a bad idea. Especially when the "handling" consists of logging and continuing. When you catch some random exception, you have no idea what the state of your program is. It's very likely that the data is corrupt and the program's state is unstable. "Log and continue" just makes the problem worse, and can lead to all kinds of interesting side effects like data corruption, infinite loops, deadlock, etc.
Your best course of action here is to refactor the code. Actually, the best course would be to send it back to the offshore developers and tell them to do it right. But that's probably too much to ask.
I'm quite late to this party but you could try this rather ugly way of doing things.
Firstly extend the Application class by adding a LastException property and a GetLastException function, see here for details.
Secondly add a line to each of the inner Catch blocks and set the LastExcepotion property:
Application.LastException = ex
There you go, no need to refactor all that offshore code.

Throwing exception in WCF service operation, anything to look out?

I am just learning WCF and wrote a Windows Service hosting a WCF service. Ever since I started it in service.msc in the remote server (physically remote, and very slow) I think I have already hit and fixed like a hundred errors here and there already. I am now finally stuck.
At this point, I have enabled tracing and message logging. The first and only function call looks like this:
[OperationContract]
public MyServiceResponse ConnectToAXDynamicsViaDotNET2BusinessConnectorWithSadFace()
{
try
{
throw new NotImplemented();
}
catch(Exception ex)
{
return new MyServiceResponse(ex, ex.Message);
}
}
[DataContract]
public class MyServiceResponse
{
// ...
}
Upon calling the operation, the client just sits and waits until timeout. Checking the trace, it records my thrown exception. So it makes me wonder if WCF actually blocks there and ignore my catch clause.
I then tested with just a simple return value without throwing and it FINALLY works.
My question is, how then can I make the above scenario work, ie. catch the exception and return a sensible result back to client? Maybe it's just the tracing that blocks me, but I want to enable tracing during this whole debugging process otherwise it's really hard to work.
Thanks for your precious help!
EDIT: Sorry, I found this right after I posted this question. Happens all the time: http://msdn.microsoft.com/en-us/library/ee942778.aspx but I have yet to read it as I got to run off now. Not sure it it will solve my problem.
Risk being downvoted, but just for documentation sake and general usefulness of having this question:
Through reading the FaultException handling articles, I guess the above behavior is due to Exception class not serializable. And the service silently disconnects itself without returning any error messages eventhough the "send (unknown) faults to client" is enabled. As for why it does so, I have no idea yet. Will update if I find out more.
I have since changed to throw new FaultException() instead of returning my own MyServiceResponses.

NHibernate Error reporting advice

This is not so much a problem as advice on best practice really. I am writing an ASP.Net MVC application, and in my DAL i am using NHibernate, but what do you do if an exception is thrown in your DAL?
Do you catch the exception in the DAL, log the error and then re-throw the exception?
Do you not even attempt to catch exeptions at all and use the Application_Error() method in the global.asax as a generic catch all?
Do you catch the exception log it and return a bool to the controller indicating a success or failure, or do you do something completly different?
Leading on from this how then do you handle informing the users? Do you show a generic "Error Occured - please try again" type page or do you show a more informative error?
This is exactly one of those 'it depends' questions. This is what I do:
Handle all exceptions in Application_Error (or similar sink-like location)
If the exception is base for business logic - say cannot have duplicates, just catch it and act upon it.
If it is an infrastructure exception and there is a good chance you can fix it by retrying - handle it in DAL.
Propagating specific exception info to user has hardly any benefit because usually the user cannot do anything about it anyway. So a generic error message usually makes do.
All unexpected and selected expected exceptions need to be logged with as much info as possible. It is also advisable that you get email with the exception info.
Now specifically to NHibernate - if NH throws an exception it is advised that you close and discard the currently active ISession and just fail. Because the session might be in an unknown/inconsistent state and trying to resurrect it can do more harm than good.
Obviously depending on scale and type of your app and number of various systems/programmers/etc. involved you really might to handle the logging yourself.