How should I handle thrown exceptions during I/O operations?

D

darylew

I've defined an input operator for my compound type. The operator reads ineach component, and any applicable delimiters. I check the stream state after each read. I'm wondering what to do after all the components are read..

I have a function to create an object given a list of components. It has aspecial set of exception classes to throw if an invalid combination of components are given. I'm figuring to have my input operator catch those exceptions, turn on the "fail" flag, then re-throw if "fail" is marked as a throwable offense. (You have to suppress the automatic throwing that could happen if a flag is set, since you what to re-throw your own error instead ofa new std::ios_base::failure object.) A bad combination of components could have theoretically picked-up before the source object is created, so it counts as a parsing error, implying the "fail" flag.

But what should happen for other exceptions? The only way my new object can create other types of exceptions is if the component-level assignments fail. I've read some stuff that seems to indicate that the "bad" flag shouldbe set and the exception re-thrown if "bad" is marked as a throwable offense. But I was thinking of doing nothing; it's not the stream's fault that assignment failed, and the new components were valid, so the I/O stream should let the exception through without any changes.

Daryle W.
 
J

James Kanze

I've defined an input operator for my compound type. The
operator reads in each component, and any applicable
delimiters. I check the stream state after each read. I'm
wondering what to do after all the components are read.
I have a function to create an object given a list of
components. It has a special set of exception classes to
throw if an invalid combination of components are given. I'm
figuring to have my input operator catch those exceptions,
turn on the "fail" flag, then re-throw if "fail" is marked as
a throwable offense. (You have to suppress the automatic
throwing that could happen if a flag is set, since you what to
re-throw your own error instead of a new
std::ios_base::failure object.) A bad combination of
components could have theoretically picked-up before the
source object is created, so it counts as a parsing error,
implying the "fail" flag.

The question depends on the context where this operator will be
used. If it's part of general input parsing, then you should
just set the failbit; users who have requested interrupts on
failure will expect a std::ios_base::failure object (and they
will expect that your operator>> will not change the status of
the exception mask, and that if it fails, failbit will be set).
Or maybe you could derive from std::ios_base::failure to provide
more information. But in every case, you should set the
failbit, and you should not allow any exception to propagate out
because of parsing errors unless one of the exception masks is
set.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,965
Messages
2,570,148
Members
46,710
Latest member
FredricRen

Latest Threads

Top