Advanced Tools Module User’s Guide : PART II Advanced Tools Module Packages : Chapter 4 Using Streams : Error Handling
Error Handling
The Streams package reports errors by throwing an exception or by using a return value in conjunction with status functions. Return values are used to report errors that occur on input stream functions that only partially succeed due to the stream reaching an end-of-file (eof). For instance, an input stream function that reads several elements might reach eof before being able to read all of the elements requested. In that case, the function puts the stream in both eof and fail mode, and returns the number of elements read. Output streams have three status member functions:
isFail() indicates that the last operation carried out on the stream failed.
isBad() indicates that an unrecoverable error occurred during the last operation carried out on the stream.
isGood() returns true if both isFail() and isBad() are false.
Input streams also have these three status member functions, along with isEof(), which indicates that the stream cannot read any more data.
Handling Errors Using the Stream Status Functions
The following code shows how to handle errors using the stream status functions:
 
filebuf fbuf;
fbuf.open("someFile", ios::in); // 1
 
RWCharInputStream charInputStream =
RWCharFromStreambufInputStreamImp::make(fbuf); // 2
 
RWCString line;
RWSize lineNumber=1;
 
while(1) {
line= "";
charInputStream.readUntil(line,'\n'); // 3
if(charInputStream.isGood()) // 4
cout << lineNumber++ << ": " << line << endl;
else
break;
}
if(charInputStream.isEof()) // 5
cout << "We have reached EOF" << endl;
//1 Creates an iostreams file buffer, and opens it in input mode. If you built the Advanced Tools Module with the Standard iostreams library, you need to qualify filebuf and other iostreams elements with std::, or you need to include using declarations.
//2 Creates a concrete instance of class RWCharFromStreambufInputStreamImp. The class is created by calling its static member function make(), which creates an instance of self and returns it as a narrow character input stream handle.
//3 Reads a line of text, and stores it in the RWCString line variable.
//4 Checks for the success of the previous operation.
//5 Checks for failure caused by eof.
Other errors are reported by throwing an instance of one of the two exception classes provided by the Streams package.
Classes RWxmsg and RWExternalErr are included in the Essential Tools Module.
Figure 19 – Exception classes in the Streams package
Streams Package Exception Classes
Class RWExternalStreamException is the base class for all exception classes in the Streams package. It returns an error message that can be accessed through the inherited member function why(), and an error code that can be accessed through the member function errorCode(). The errorCode() function returns a value of type ErrorCode, which is an enumeration. Error codes 0 through 11 have the following meaning:
ok
everything is fine
flush
error while flushing the stream
write
error while writing to the stream
read
error while reading an RWByte, char, wchar_t, or RWUChar
get
error while reading a datatype
internalOstream
the internal ostream object is in a fail or bad state
internalIstream
the internal istream object is in a fail or bad state
featureNotSupported
reports a feature not currently supported due to compiler limitation
outOfMemory
the last memory allocation request failed
invalidParameter
one of the parameters has been assigned an invalid value
invalidUnicodeEncoding
a sequence of RWUChar does not represent a valid sequence of UTF-16 character(s)
invalidUTF8Encoding
a sequence of bytes is not formatted according to UTF-8
Error codes 12 through 499 are not currently assigned, but are reserved by Rogue Wave for future use. If you want to return your own error code, use a value greater or equal to 500.
Class RWIncompleteStreamOperation is thrown to report operations that have been partially fulfilled. For instance, an output stream function writing an array of elements might write several elements before encountering a fatal error. In this case, the function throws an instance of class RWIncompleteStreamOperation, which can be queried using the member function elementsProcessed() to get the number of elements successfully written prior to failure.
The following code shows how to handle stream exceptions:
 
try {
// some stream operation
}
catch(const RWIncompleteStreamOperation& e) {
cout << e.why() << endl;
cout << "the number of element(s) successfully processed is: "
<< e.elementsProcessed() << endl;
if (e.errorCode() == RWExternalStreamException::outOfMemory)
cout << “we ran out of memory” << endl;
}
catch(const RWExternalStreamException& e) {
cout << e.why() << endl;
if (e.errorCode() == RWExternalStreamException::outOfMemory)
cout << “we ran out of memory” << endl;
}