Which Error Handling Model Is More Robust? - vb.net

I'm kind of torn between these two error-handling models:
Create a boolean Error and a string ErrorMessage property for your object. Catch all exceptions internally in the object's methods and pass the messages along using conditional logic from the caller, ie:
Dim o As New MyObject
o.SomeMethod()
If Not o.Error Then
'Do stuff'
Else
Dim msg As String = o.ErrorMessage
'do something with message'
End If
Throw exceptions in your object and handle them on the outside with Try Catch logic:
Dim o As New MyObject
Try
o.SomeMethod()
'Do stuff'
Catch ex As Exception
Dim msg As String = ex.ErrorMessage
'do something with message'
End Try
To me, it seems like the same amount of code either way, except that you have property code for the Error and ErrorMessage properties. However, you also can tell when an error occurs without having to check for exceptions. Which pattern should I go with?

I have decided to go with throwing exceptions instead of using error/return codes. I just recently looked really hard into this.
The #1 reason to throw exceptions is there is a possibility you can forget to check the error code. If you don't check it, then you will continue working while the error exists. With exceptions though, if you forget to handle them, then the exception will raise to the top and stop all processing. It is better for this to happen than to continue after unknown errors have occurred.
For more info check out the Exception chapter in Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, Second Edition by Addison-Wesley.
Joel Spolsky actually prefers error/return codes over exceptions but a lot of people disagree with him. Joel's post in favor of return codes can be found here. Check out this blog post and all of the comments with some good discussion regarding this subject.

Prefer #2. For details, see this excerpt on Exception Throwing from the development of Microsoft's excellent Framework Design Guidelines, as Dennis mentioned. Note especially the section on Exceptions and Performance.
Short version:
Do not return error codes.
Do report execution failures by throwing exceptions.
Do not use exceptions for normal flow of control.
I highly recommend reading the book for a full discussion, complete with commentary from a number of the Microsoft luminaries.

Exceptions should be used when something exceptional has happened.
e.g. you are passed a null (nothing) object when you expect one.
Uncle Bob recommends Exceptions over Error codes in his book Clean code.
He says
The problem with these [error codes] approaches is that they clutter the caller. The caller must check for errors immediately after the call. Unfortunately it's easy to forget. For this reason it is better to throw an exception when you encounter an error. The calling code is cleaner. Its logic is not obscured by error handling.

The biggest issue I have with the first one is that it's passive, easily overlooked and not very standardized. How will a programmer know to check that property? Or which properties / methods can possible set an error? Or which property / method access caused the error to be set?
For example. In your first sample code if o.Error is True, it's unclear whether the initialization of the object or the call to SomeMethod caused the flag to be set.
The exception model is an unignorable way of telling your users that an error occurred. It cannot be avoided without explicit code to handle the situation.

They are both accepted forms of error handling, however the preferred choice for .NET languages is to use exceptions.
There are a few problems with using return codes (either numeric or boolean), the two biggest being:
Easily overlooked/ignored by programmers.
Can't be used in all situations. What happens if your constructor fails? It's not possible for you to return a value explicitly from a constructor.
For these reasons alone, you should use exceptions. Exceptions provide a clean, standardized way to indicate and any failure no matter where it arises.
You will also end up with less code overall as you should only catch exceptions when and where you can safely and appropriately handle that exception.

I recommend using both.
Why?
"Use the right tool for the job"
The "problem" with return codes is that people often forget to handle them. However, exceptions don't solve this problem! People still don't handle exceptions (they don't realise a certain exception needs to be handled, they assume somebody up the stack will handle it, or they use a catch() and squash all errors).
While an unhandled return code might mean the code is in an unstable state, an unhandled exception often guarantees that the program will crash. Is this better?
While a return code is easily identifiable when writing code, it is often impossible (or just tediously time-consuming) to determine what exceptions might be thrown by a method you are calling. This typically results in a lot of very poor exception handling.
Exceptions are supposed to be used for "errors". Therein lies the difficulty. If a file is not found when you try to open it, is that an "error", or an "expected situation"? Only the caller knows. Using exceptions everywhere essentially elevates every piece of status information into an error.
Ultimately, error handling is something a programmer has to work at. This problem exists in both return codes and exceptions.
Thus, I use return codes for passing status information (including "warnings"), and exceptions for "serious errors". (and yes, sometimes it's hard to judge which category something falls under)
Example case from .net:
Int32.Parse throws exceptions (even though none of its exceptions are errors - it is up to the caller to verify the results and decide for themselves if the result is valid). And it's simply a pain (and a performance hit) to have to enclose every call to it in a try/catch. And if you forget to use a try/catch, a simple blank text entry field can crash your program.
Thus, Int32.TryParse() was born. This does the same thing, but returns an error code instead of an exception, so that you can simply ignore errors (accepting a default value of 0 for any illegal inputs). In many real life situations this is much cleaner, faster, easier and safer to use than Int32.Parse().
"TryParse" uses a naming convention to make it clear to the caller that errors might occur, that should be correctly handled. Another approach (to force programmers to handle errors better) is to make the return code into an out or ref parameter, so that the caller is explicitly made aware of the need to handle returned errors.

Related

Can a language have exceptions without a type hierarchy?

In my experience, every language which supports exceptions has a hierarchy of exception types. This allows a single catch clause to match a group of related exceptions by catching their common parent. For example, part of Python's hierarchy:
FloatingPointError < ArithmeticError < Exception < BaseException
Go, on the other hand, famously does not support exceptions and also has "no type hierarchy". Some people think exceptions should be added to Go - would it be possible to do this without adding a type hierarchy?
Are there other languages which have exceptions but no type hierarchy? Do they group related exceptions in some other way?
SuperTalk has effectively no data types, but has exceptions. Basically you throw an error code and check that. That's also how many early macOS application frameworks worked, even in C++.
So just as an object can be approximated by using a simple data structure with a type selector, exceptions can be made to work.
on doFoo
throw "myError"
end doFoo
on startUp
try
doFoo
catch tError
if tError = "myError" then
-- do something about it
else
throw tError
end if
end try
end startUp
Instead of "myError", you can throw any string or number, so you could use a formatted string, like "copyFileError,/path/to/source/file.txt,/path/to/dest/file.t‌​xt" (of course with proper escaping of dangerous characters like "," in this case) and then just compare the first item in this list to tell whether it's the error you want to handle.
If you're just going with error numbers without any additional payload, you can segment the number space to get error "classes" e.g. "fatal errors are negative, recoverable ones positive" or "1-100 are file system errors" or whatever (see HTTP status code for an example of using error code ranges to define error classes).
I'd rather post this as a comment, but the sentiment was too long to get across within the limitations of a comment. I am aware that this is primarily opinion based, and I apologize for that.
Go does not support exceptions because it does not need to. Exceptions are a crutch that developers have been lured into becoming dependent on because they don't want to handle errors properly. In Go, it is idiomatic to handle every error, on the spot, every time. If you do this, your programs run better, and you are aware of exactly when/where errors happen and you can fix them. Using catch in other languages ends up being more difficult to debug as you are not always aware of exactly where the error originally happened. By wrapping your code in try catch blocks, you essentially mask the bugs in your code. try and catch are also terribly inefficient because all of the optimizations in the binary grind to a halt as the program has to figure out what unexpectedly happened. Using errors properly in Go circumvents this because you capture errors and handle them, thereby "expecting" them as an eventuality and handling them properly.

Etiquette of error codes in COM

In a COM object generally there are two ways of indicating that a function failed (that I'm aware of):
return S_OK and have an [out] parameter to give failure info
return a failure HRESULT, and use ICreateErrorInfo to set the info.
Currently what I am doing is using the failure-HRESULT method for failures that are "really bad", i.e. my object will be basically inoperable because this function failed. For example, unable to open its configuration file.
Is this correct, or should failure HRESULTs be reserved only for things like dispatch argument type mismatches?
The short version:
In COM you should use HRESULTs (and strive to use ISupportErrorInfo, etc.) for most/all types of error conditions. The HRESULT mechanism should be viewed as a form of exception throwing. If you are familiar with that, consider "Error conditions" as anything for which you would normally throw an exception in a language that supports them. Use custom return values for things for which you would not normally use exceptions.
For example, use a failure HRESULT for invalid parameters, invalid sequence of operations, network failures, database errors, unexpected conditions such as out-of-memory, etc. On the other hand, use custom out parameters for things like 'polling, data is not ready yet', EOF conditions, maybe 'checked data and it doesn't pass validations'. There is plenty of discussions out there discussing what each should be (e.g. Stroustrup's TC++PL). The specifics will heavily depend on your particular object's semantics.
The longer version:
At a fundamental level, the COM HRESULT mechanism is just an error code mechanism which has been standardized by the infrastructure. This is mostly because COM must support a number of features such as inter-process (DCOM) and inter-threaded (Apartments) execution, system managed services (COM+), etc. The infrastructure has a need to know when something has failed, and it has a need to communicate to both sides its own infrastructure-related errors. Everybody needs to agree on how to communicate errors.
Each language and programmer has a choice of how to present or handle those errors. In C++, we typically handle the HRESULTs as error codes (although you can translate them into exceptions if you prefer error handling that way). In .NET languages, failure HRESULTs are translated into exceptions because that's the preferred error mechanism in .NET.
VB6 supports "either". Now, I know VB6's so-called exception handling has a painful syntax and limited scoping options for handlers, but you don't have to use it if you don't want to. You can always use ON ERROR RESUME NEXT and do it by hand if you think the usage pattern justifies it in a specific situation. It's just that instead of writing something like this:
statusCode = obj.DoSomething(param1)
If IS_FAILURE(statusCode) Then
'handle error
End If
Your write it like this:
ON ERROR RESUME NEXT
...
obj.DoSomething param1
IF Error.Number <> 0 Then
'handle error
End If
VB6 is simply hiding the error code return value from the method call (and allowing the object's programmer to substitute it for a "virtual return value" via [retval]).
If you make up your own error reporting mechanism instead of using HRESULTs, you will:
Spend a lot of time reinventing a rich error reporting mechanism that will probably mirror what ISupportsErrorInfo already gives you (or most likely, not provide any rich error information).
Hide the error status from COM's infrastructure (which might or might not matter).
Force your VB6 clients to make one specific choice out of the two options they have: they must do explicit line-by-line check, or more likely just ignore the error condition by mistake, even if they would prefer an error handler.
Force your (say) C# clients to handle your errors in ways that runs contrary to the natural style of the language (to have to check every method call explicitly and... likely throw an exception by hand).

Validation in setters: What approach is better?

I have dispute with my friend.
He said me that this code:
method SetBalance(balance) {
if (balance > 0) {
this.balance = balance;
return true;
}
return false;
}
is better then this:
method SetBalance(balance) {
if (balance < 0) {
throw new InvalidArgumentException("Balance couldn't be negative")
}
this.balance = balance;
}
My question is: "Which approach is better for validation?" and why?
Thank you.
Ah. Return status versus exception.
I prefer throwing exceptions, because you can't really ignore an exception. The program either crashes, or you have to explicitly catch and handle it.
You can just ignore a return status.
Besides, isn't this the reason exceptions exist in modern programming? To deal with, well... exceptions (balance <= 0, something that shouldn't happen).
In case of setters, developers will never expect the return value from those methods since they feel that this will anyway will take care of setting the value.
In case, if there is an exception, then this will help then to understand that something is really wrong and look after the code again.
Instead of runtime exception, you better define your own exception like InvalidBalanceException and specify that this method will throw this exception in the signature itself. This avoids surprises at testing phase and decide the business logic in development phase itself.
Return value is easily ignored. Here you have clear coding bug, so crash loud. I would even halt/segfault/stop program - the exception may still be caught. We live in "ideal world", but imagine our less fortunate colleagues - they might well go for gagging error signalling facility being unable to deal with the root cause (insert here more complicated error scenario). Coding gets much easier when you dont give clients ways to do things wrong way.
Besides the answers given already, returning a boolean value in a function named "setFoo" is very misleading. If you translate a boolean value you come up with yes/no. So a function that returns booleans in oop should be readable as a question that gives yes/no as an answer, e.g. isBalanceSet.
In discussion with collegues we considered the only valid return-value for a normal setter is the class itself for fluent-interfaces.
Regarding your question throwing exceptions is the better solution if the class actually validates its properties itself ;)
My personal opinion: both approaches has its uses. It depends on why the situation arose, could it be prevented, what the client could have done to prevent it.
Server:
method SetBalance(int balance)
{
// do something only if balance >= 0
}
Client:
myServer.SetBalance(balance);
Case 1:
The situation arises only because of a bug somewhere (in server or client). Throw exception. Let the responsible party fix its code.
Case 2:
A bad input is received from some external dependency. The client could easily check the precondition. Throw exception, let the client fix its code if she is unhappy with that.
if(balance>0)
myServer.SetBalance(balance);
else
//take appropriate action.
Case 3:
A bad input is received from some external dependency. The client could not easily check the precondition. Example: it would require the client to parse a string, which is the server's job. Here, it makes sense that the server should return success:
bool succeeded = myServer.SetBalance(balance);
if(!succeeded)
//take appropriate action.
After writing my answer down, I noticed it all boils down to this: The client should not have to use try-catch to call the method SetBalance. (Either it's a bug so don't catch the exception, or check the precondition yourself, or inspect the return value)
Here is a good reading on a related subject: http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx
Edit:
Jojo makes a good point. Rename the method TrySetBalance() if there is a probability that it might fail.
Exceptions handling is the method of choice to handle errors in OOP, whether it is runtime error or logic error. One of the arguments to justify exception handling is that, if error code is used a client of a function may forget to check the error code leading to a potential bug which may not be easily found. Whereas, if exception handling is used, even if it is not caught, it will propagate until it is handled. So, OOP purists always advice using exception handling.

What is the main use of NSAssert Vs. NSException

What is the main use of NSAssert Vs. NSException. What is more recommended and when?
Assertions are generally used during development only and are compiled-out of the app when in release mode (this is controlled by NS_BLOCK_ASSERTIONS). Exceptions, on the other hand, can be used at all times.
When an exception is thrown, it travels back up the call chain, until it is either caught (and reported, ignored, or another exception is thrown) or it reaches the top, in which case it will cause the app to crash. It can be considered part of the contract of a class method and needs to be documented so the caller can handle this correctly.
Assertions are really a runtime developer check that ensure that something (generally a instance variable) is in a certain state and if it's not then abort() in order to bring the issue to the developers attention. It's a developer sanity check to check that something is in the state the developer expects it to be.
Assertions are used to find things that should never happen under any circumstances if your code is working the way you think it should be. If they are happening, there is a bug in your code and you want to know about it, at least if it happens during testing. (Most people turn off assertions in released code.)
In contrast, exceptions are used to find things that have gone wrong over which you have no control. For example, if your application is dependent on a database server and that database server is unavailable, that might raise an exception in your code. (Do not make the mistake of using exceptions for things like user input validation. If it's regular program flow--the user forgot to enter a field or whatever--that's not an exception. Exceptions should be exceptional.)

Why do many languages treat Exception-objects as first-class citizens?

When we get an objects that is actually are exceptions, we can do with them anything that we can do with ordinar objects in our language. We can pass them as an argument, we can store them in some collection and, what is the worst, we can return them as a result from the methods!
So there is a possibility for someone to write smelly code like this:
public Exception doSomethingCritical()
{
Exception error = null;
try
{
...
}
catch (Exception e)
{
// maybe at least here is the logging of the error if we are lucky
error = e;
}
return error;
}
So the question is why is the concept of an Exception-object is a first-class citizen in many OO languages? Maybe it is better if we have only limited constructions in the language that is allowed for exception-objects (like throw).
The problem with treating exceptions as a special case, and allowing only limited functionality with exceptions is that ultimately somewhere every good program needs to do something with exceptions, whether it be a global error-handler or a limited item that appropriately deals with the exception. By making exceptions first class citizens, there are many benefits, such as:
Allowing subclassing of exceptions. This is invaluable for exception handling as code dealing with exceptions can narrow their scope and deal only with exceptions they know how to deal with. I'd go so far as to say that any non-global exception handling routine that is catching just "Exception" is probably doing it wrong.
Passing data along with exceptions. Exceptions aren't very useful if the only thing you know in your catch logic is that an exception occurred. Stack traces, messages and even custom data for certain exception types are invaluable in identifying and resolving the problem that caused the exception.
Creating error handling routines that use OOP themselves. If exceptions couldn't be passed as objects, you couldn't for instance have a library that deals with exceptions - well, at least not a well written one.
Besides all of that, there's no way to guard against bad exception handling like you posted above. Even if an exception wasn't a first class citizen, there's no way to stop a developer from eating any and all exceptions and carrying on their merry way (at least, without fundamentally breaking how we think of exceptions)
My opinion.
I think you are confusing two different things: the Exception and the Exception throwing.
The exception throwing is an out-of-band process that allows you to throw an object through a preferential, lateral channel. This object can be intercepted and handled through the Exception catching mechanism.
The Exception is just one object that you can (preferentially) throw via the Exception throwing out-of-band channel. Of course, this channel can have requisites for the interface of the object being thrown, requisites that are satisfied by the Exception class interface.
You are looking at the issue the other way around. Indeed you can do horrors, but there's nothing special about the Exception object, apart of being the preferred object that is thrown in the out-of-band channel.
I've never actually seen that example you've used. And I can't see how not allowing people to return exceptions will make a big difference to conceptually poor code - compare
public int doSomethingCritical()
{
int error = 0;
try
{
...
}
catch (Exception e)
{
// maybe at least here is the logging of the error if we are lucky
error = E_SOMETHINGBAD;
}
return error;
}
Whereas if you create a new kind of "thing" to be used for exceptions that isn't the same as an object, there is a design and learning overhead disadvantage.
How would you be able to inherit from the base exception class and derive your own exception class for your module if they were not first type citizens?
I don't see why I shouldn't be allowed to pass and return exceptions as normal method parameters. What if I were writing an Exception Handling library? What if I were writing a unit test assertion that compared exceptions?
Because life is a lot easier that way. Among other things, it means that the exception object can contain information that the program can use to correct the exceptional situation (perhaps with human intervention).
Abend is so 1960s.
I'm not sure the example you give is a strong enough case for not having exceptions as objects. After all you COULD do all kinds of "smelly" or "bad" things while programming. However thats precisely the reason we want good programmers. Just because I can do dsomething like :
def get_total
return nil
end
surely doesnt mean I should not allow nil as an instance of an object!