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;
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.
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;
}