|
-
January 28th, 2012, 09:33 PM
#1
Error Handling Strategies
From what I understand, exceptions are very slow and are not useful for returning error information repeatedly in a loop, but most class methods in Microsoft’s APIs make great use of exceptions, to the point where handling every possible scenario gets annoying, because it becomes necessary to write a lot of try/catch blocks. In my opinion, try/catch blocks are not very attractive and have performance issues. It would be better for me if in all classes I define myself, I could somehow avoid forcing the caller to handle exceptions, especially when the caller code is written by me. There has to be some strategy that is consistent with the elegance of C#, that does not require me to use exceptions. I need a strategy that will be used throughout all my projects consistently. But I am not sure exactly what strategy to use.
Since functions can only return objects/values of a specific type, would it make sense to return both success and failure information? I would think that error objects would be of a different type than objects resulting from success, so they could not both be returned. Maybe I should have a result object, wherein I can specify a class type for errors and a class type for the result. But would this be at all elegant? Or should I use reference parameters? In your opinion, what is the best way to handle errors without having to deal with exceptions? I am sure that finding an alternative will not only make coding less tedious for me, but also improve performance in loops.
-
January 29th, 2012, 07:49 AM
#2
Re: Error Handling Strategies
Setting up a try/catch/finally has nearly no performance penalty. Actually throwing an exception has a performance hit as the runtime has to calculate the stacktrace, do security checks and unwind the stack correctly until it finds a matching 'catch' statement or the application unwinds completely.
The best thing about exceptions is you should only catch them if you can handle them. For example:
Code:
FileStream file = null;
try {
file = File.OpenRead ("some_file");
} catch (FileNotFoundException) {
} catch (FileAccessException) {
} catch (IOException) {
} catch (Exception) {
}
using (StreamReader reader = new StreamReader (file)) {
Console.WriteLine (reader.ReadLine ());
}
Technically i could handle every exception type and end up with a gigantic mess of code which makes it hard to read. However if i do not care what exception happens i could just write:
Code:
try {
using (StreamReader reader = new StreamReader (File.OpenRead ("Some_file")) {
Console.WriteLine (reader.ReadLine ());
}
} catch {
// Maybe log an error, maybe just ignore
}
Similarly, if I'm writing a function which opens a Socket, then calls 20 other functions where they each send or receive data from the socket, I only have to put a try/catch (SocketException) in the root function. The idea is that you only catch an exception when you can do something useful with it. Sometimes 'something useful' is printing an error message. Sometimes it's ignoring the error completely. Sometimes you have to exit the application. It just depends.
Code:
Socket s = null;
try {
s = ConnectToServer ();
SendHandshake (s);
ReceiveHandshake (s);
SendEncryptionHeader (s);
ReceiveEncryptionHeader (s);
FinaliseEncryption (s);
} catch (Exception ex) {
// I could not connect to the server because it didn't exist or the encrypted connection could not be established
Console.WriteLine (ex);
}
Each of those subfunctions does not need to handle the case where the socket throws an exception because the main function does.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
January 29th, 2012, 10:29 AM
#3
Re: Error Handling Strategies
Just a few words in addition to the above.
 Originally Posted by Guidosoft
From what I understand, exceptions are very slow and are not useful for returning error information repeatedly in a loop [...]
You understood it wrong.
Exceptions are only used for exceptional circumstances, but people often wrongly use them for other stuff, to return data or derive logic from them, which of course leads to bad performance.
Once conditions are met for an exception to be raised, normal code execution simply stops at that point, and control is transferred to the exception handling mechanism. Generally speaking, when used properly, you don't need to worry about the performance at all when it comes to exceptions, because exceptions are not part of your normal program logic.
Now, what exactly is an "exceptional circumstance" depends on the nature of your application. If you're developing a scientific application where precision is an imperative, then you simply cannot allow normal execution to continue if the user provided invalid input, or if certain important preconditions aren't met, or something is missing in the overall system, etc. - so you throw an exception, gracefully handling it where appropriate, turning an ugly stack trace into a meaningful error message (from the user's perspective). On the other hand, if you're developing a game, and some data is imprecise, missing or incorrect, you can just programmatically "guess it", or simply use a default value, and your game/virtual world will generally run just fine. You wouldn't throw an exception in that case. There, an "exceptional circumstance" would be something like if a connection to a server fails, or if there is no more memory available, or the if graphics/audio/input system could not be initialized.
For example consider this method, for which the valid input is within [0.0, 1.0]:
void SetIntensity(double amount);
What if it receives 5.4, or -20.07?
You either decide to throw an exception, or simply coerce the values to the closest value in the valid range.
Your choice will depend on the nature of your application, on how important it is to inform the end user about the error.
Also, if you're writing a library or a framework, you can provide two methods that have the same basic functionality, but different behavior with regard to error handling.
.NET class library has such methods - for example:
int.Parse(string); // throws exceptions
and
int.TryParse(string, out int); // returns an error code
Last edited by TheGreatCthulhu; January 29th, 2012 at 10:32 AM.
-
January 29th, 2012, 03:47 PM
#4
Re: Error Handling Strategies
Alright, thanks for the information about exception handling.
One problem I have though, is knowing the appropriate scenario for throwing an exception. From what I've gathered from this thread, catching exceptions is not costly but throwing exceptions is. Before I had encountered a problem where I had to read through numerous records in a file, and report to the top calling code the lines at which each invalid record was found. So, being told that exception handling was best practice, I throw an exception for every invalid record, and caught them in a loop to determine which records were invalid. The performance suffered so greatly that a file which ought take only one second to process showed no sign of ever being finished. When I replaced my exception handling code with code that returned objects with a property indicating whether it was valid or not, the performance was where it was before.
I guess it was because in this case I was using exceptions as part of the program logic, since I depended on it repeatedly inside a loop. So, I am not perfectly clear on when to use exceptions.
-
January 29th, 2012, 04:45 PM
#5
Re: Error Handling Strategies
In this case, the validation for each line in the file wasn't really an exceptional case (especially since you needed to return an array of failed line #'s).
Perhaps it would be better to validate line by line and push the failed line numbers into a List<int> error list. When you get to the end of the file, check the count of items in the error list and throw a single exception containing the line error #'s.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|