Boost.Iostreams + error handling

Hi there, Are exceptions the only way to propogate an error out of and IOStreams.Device policy? We have a lot of code using this style std::istream is(file); if(is) { .... } and would like not to have to change it all over to use ios exceptions but I can't see a way to avoid it. Is it possible? thanks Martin

Martin Slater wrote:
Hi there,
Are exceptions the only way to propogate an error out of and IOStreams.Device policy? We have a lot of code using this style
std::istream is(file);
if(is) { .... }
and would like not to have to change it all over to use ios exceptions but I can't see a way to avoid it. Is it possible?
When you use a stream, rather than a streambuf, exceptions are caught automatically and translated into stream state, unless you set the exception mask to request that exceptions be propagated. (See http://www.boost.org/libs/iostreams/doc/index.html?path=3.10) The only time you have to be prepared to handle exceptions is when you are using a raw stream buffer.
thanks
Martin
Jonathan

When you use a stream, rather than a streambuf, exceptions are caught automatically and translated into stream state, unless you set the exception mask to request that exceptions be propagated. (See http://www.boost.org/libs/iostreams/doc/index.html?path=3.10)
The only time you have to be prepared to handle exceptions is when you are using a raw stream buffer.
Just to be sure, were using an old version with boost 1.32 where stream == source. What I'm finding is that in the constructor where it is passed a file to open it gets passed through to our code and the file doesn't exist the only way we have of reporting an error is through an exception but this doesn't get caught and translated by the stream_facade but propogated straight out to our code. Has this behaviour changed in 1.33 or is there something i'm missing? thanks Martin PS> Unfortuantly we cannot upgrade to 1.33 at the moment either. -- No virus found in this outgoing message. Checked by AVG Anti-Virus. Version: 7.0.344 / Virus Database: 267.10.24/100 - Release Date: 13/09/2005

Martin Slater wrote:
When you use a stream, rather than a streambuf, exceptions are caught automatically and translated into stream state, unless you set the exception mask to request that exceptions be propagated. (See http://www.boost.org/libs/iostreams/doc/index.html?path=3.10)
The only time you have to be prepared to handle exceptions is when you are using a raw stream buffer.
Just to be sure, were using an old version with boost 1.32 where stream == source.
I don't think stream was ever equivalent to source.
What I'm finding is that in the constructor where it is passed a file to open it gets passed through to our code and the file doesn't exist
Are you talking about errors which occur in Source constructors, e.g. (using 1.32 naming) stream_facade< random_source > in; in.open( random_source(4320243) ); // What happens if // constructor fails? ?
the only way we have of reporting an error is through an exception but this doesn't get caught and translated by the stream_facade but propogated straight out to our code.
stream_facade doesn't catch and rethrow exceptions which occur during open(). You can change this by modifying stream_facade::open_impl so that it looks something like the following (I'm not sure exactly what the code in your version looks like): void open_impl(const Device& dev BOOST_IOSTREAMS_PUSH_PARAMS()) { this->clear(); try { this->member.open(dev BOOST_IOSTREAMS_PUSH_ARGS()); } catch(...) { this->clear(std::ios_base::badbit); if (this->exceptions() & std::ios_base::badbit) throw; } } Alternatively, you could give your Source a member function 'good' returning a bool, and do stream_facade< random_source > in( random_source(888) ); if (in->good()) { ... } Lastly, you could set a flag in the constructor and have subsequent read or write requests fail is the construction was unsuccessful. I'll consider adding the above code to open_impl() for 1.34 (or maybe 1.33.1, since it seems like a harmless change, and improves usability). Thanks for bringing this to my attention.
Has this behaviour changed in 1.33 or is there something i'm missing?
thanks
Martin
Jonathan

Jonathan Turkanis wrote:
Just to be sure, were using an old version with boost 1.32 where stream == source.
I don't think stream was ever equivalent to source.
My bad, sorry, I didnt have the code in front of me.
the only way we have of reporting an error is through an exception but this doesn't get caught and translated by the stream_facade but propogated straight out to our code.
stream_facade doesn't catch and rethrow exceptions which occur during open(). You can change this by modifying stream_facade::open_impl so that it looks something like the following (I'm not sure exactly what the code in your version looks like):
void open_impl(const Device& dev BOOST_IOSTREAMS_PUSH_PARAMS()) { this->clear(); try { this->member.open(dev BOOST_IOSTREAMS_PUSH_ARGS()); } catch(...) { this->clear(std::ios_base::badbit); if (this->exceptions() & std::ios_base::badbit) throw; } }
Alternatively, you could give your Source a member function 'good' returning a bool, and do
stream_facade< random_source > in( random_source(888) ); if (in->good()) { ... }
Lastly, you could set a flag in the constructor and have subsequent read or write requests fail is the construction was unsuccessful.
I'll consider adding the above code to open_impl() for 1.34 (or maybe 1.33.1, since it seems like a harmless change, and improves usability). Thanks for bringing this to my attention.
Thanks for all the details i'll make your suggested change locally. Getting it in 1.33.1 would get my vote as the behaviour as is is surprising. Anyway an extremely useful library , thanks for all the good work. Martin -- No virus found in this outgoing message. Checked by AVG Anti-Virus. Version: 7.0.344 / Virus Database: 267.10.25/102 - Release Date: 14/09/2005
participants (2)
-
Jonathan Turkanis
-
Martin Slater