views:

50

answers:

7

Let's say you have a function (X) that takes a single object and does some work with it. It can fail in some way:

function X(obj) throws SomeException

And I have a collection of these objects, and want to run X on all of them. So I wrap that up in its own function:

function Y(objs)
  foreach obj in objs
    X(obj)
  end
end

What is the best way of handling the exceptions returned by X?

One obvious choice would be to not catch the exception at all, causing the processing of the collection to stop at the first failure.

Another would be to catch each exception as it occurs and save it aside. At the end, you could then throw a new exception if there were any exceptions at all. You could optionally choose to include these exceptions as nested exceptions of the new exception.

Another would be to ignore the exception completely, returning something like a boolean array that marks success/failure, or even returning the array of exceptions that occurred.

+1  A: 

I think all three that you listed are valid, and which one you pick depends on the specific use case - that is, which is most appropriate for your application. "Best practices" can't trump application logic, and well-written practices don't dictate logic.

danben
+1  A: 

There is no one right answer.

All of what you said is an option. You can do nothing, let it propagate. You can catch and immediately rethrow with more information about which object was being processed when the exception occurred, which is much better. You can catch and throw one exception at the end, optionally with all inner exceptions. You can also catch and log exception and not rethrow at all.

From time to time I've used all of these techniques. It really depends on what your app is specifically doing and your business requirements.

Sam
+1  A: 

This would completely depend on the state of the list after completion.

If it is acceptable that certain items do not process correctly, then either swallow them or return a boolean indicating success/failure.

If it is required that all items process correctly, I would have the exception bubble up rather.

You might want to avoid creating an exception list, you might rather want to check the items before hand and return a list of items that do not meet the required state.

astander
+1  A: 

The answer depends entirely on what you're doing with your objects, and the context in which it happens.

If it's okay that not all are processed, then obviously you don't want to fail hard and terminate execution - allowing the calling code access to the exception details might be helpful, or it might not be.

If it's important that all are processed, then you return some value saying it failed, or let the exception bubble further up if the operation is vital to the program state.

Michael Madsen
+1  A: 

It depends very much on the contxt of what you are doing.

If every item must be processed then breaking at the first exception would may be the best option.

If you are committing a bunch of items which have been parsed from a third party source and you are expecting some failures keeping a note of the failed items and returning a status object may well be the way to go.

runrunraygun
+1  A: 

This is a very slippery slope you're riding. Handling an exception requires the program to restore the state of the program to the state it had before the exception was thrown so it can meaningful continue. That's going to be mighty difficult to do, the collection obviously contains an object that cannot be processed. Restoring state would require restoring the collection as well.

Maybe that's possible. But not in the code in your snippet, it doesn't has any code that appears to be responsible for entering objects in the collection. You should not catch an exception if you don't know how to restore state.

Hans Passant
+1  A: 

Well I guess is pretty more of the same, but it stands a no right or wrong answer, just the more right or worg for some given case.
To capture and continuing rethrowing exceptions can be rather costy to the machine, but it can be your wanted behavior.
I can give two pointers:
- if you intend to discard the collection process if one is wrong just capture the exception and do whatever you may feel like it;
- if you want to assert whether some item is write or wrong, asserting all, you should capture them all, and if you feel like it, either just log it or discard it, or save all those 'inner exceptions' and rethrow or treat them all at the end of the process.

What is exactly the situation?

NoProblemBabe