views:

139

answers:

5
+5  A: 

In this case it's better to throw it in the lower-level Foo function so that you don't have to copy the validation and exception throwing code in all of your wrappers. In general using exceptions correctly can make your code a lot cleaner by removing a lot of data validation checking that you might otherwise do redundantly at multiple levels in the call stack.

bshields
neuro
+1  A: 

The sooner you catch the exceptiont the better. The more specific the exception is - the better. Don't be scared of including most of your code into a try catch blocks, apart fromt he declaration.

For example:

int count = 0;
bool isTrue = false;
MyCustomerObject someObject = null;

try
{
   // Initialise count, isTrue, someObject. Process.
}
catch(SpecificException e)
{
// Handle and throw up the stack. You don't want to lose the exception.
}
vikp
+1  A: 

I like to use helper functions for this:

struct StreamException : std::runtime_error
{ 
    StreamException(const std::string& s) : std::runtime_error(s) { }
    virtual ~StreamException() throw() { }
};

void EnsureStreamIsGood(const std::ios& s)
{
    if (!s.good()) { throw StreamException(); }
}

void EnsureStreamNotFail(const std::ios& s)
{
    if (s.fail()) { throw StreamException(); }
}

I test them immediately before and after performing stream operations if I don't expect a failure.

James McNellis
+1  A: 

Traditionally in C++, stream operations don't throw exceptions. This is partly for historic reasons, and partly because streaming failures are expected errors. The way C++ standard stream classes deal with this is to set a flag on a stream to indicate an error has occurred, which user code can check. Not using exceptions makes resumption (which is often required for streaming ops) easier than if exceptions were thrown.

anon
Still, there's always the exception mask of the stream objects in case one wanted to have exceptions when bad things happen. In my opinion, it should be set to *badbit*: fails in extractions, as you said, are expected, as well as eof, but if there's an IO error there's not much you can do, at least not in your "normal" file read/write code.
Matteo Italia
+2  A: 

I would prefer not to delay notifying an error. If you know after you have created the stream, that it is no good, why call a method that works on it? I know that to reduce code-redundancy you plan to move it further down. But the downside of that approach is a less-specific error message. So this depends to some extent on the source-code context. If you could get away with a generic error message at the lower-function level you can add the code there, this will surely ease maintanence of the code especially when there are new developers on the team. If you need a specific error message better handle it at the point of failure itself.

To avoid code redundancy call a common function that makes this exception/error for you. Do not copy/paste the code in every wrapper.

Abhay