Occasionally, and especially with sockets, streams can experience errors that prevent further processing of stream data. Generally, errors indicate the absence of something at one end of a stream, such as the crash of a remote host or the deletion of a file being streamed. There is a little that a client of a stream can do when most errors occur except report the error to the user. Although a stream object that has reported an error can be queried for state before it is closed, it cannot be reused for read or write operations.
The NSStream and NSOutputStream classes inform you if an error occurred in several ways:
If the stream object is scheduled on a run loop, the object reports a NSStreamEventErrorOccurred
event to its delegate in a stream:handleEvent:
message.
At any time, the client can send streamStatus
to a stream object and see if it returns NSStreamStatusError
.
If you attempt to write to an NSOutputStream object by sending it write:maxLength:
and it returns -1, a write error has occurred.
Once you have determined that a stream object experienced an error, you can query the object with a streamError
message to get more information about the error (in the form of an NSError object). Next, inform the user about the error. Listing 1 shows how the delegate of a run loop-scheduled stream object might handle an error.
Listing 1 Handling stream errors
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode { |
NSLog(@"stream:handleEvent: is invoked..."); |
switch(eventCode) { |
case NSStreamEventErrorOccurred: |
{ |
NSError *theError = [stream streamError]; |
NSAlert *theAlert = [[NSAlert alloc] init]; // modal delegate releases |
[theAlert setMessageText:@"Error reading stream!"]; |
[theAlert setInformativeText:[NSString stringWithFormat:@"Error %i: %@", |
[theError code], [theError localizedDescription]]]; |
[theAlert addButtonWithTitle:@"OK"]; |
[theAlert beginSheetModalForWindow:[NSApp mainWindow] |
modalDelegate:self |
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) |
contextInfo:nil]; |
[stream close]; |
[stream release]; |
break; |
} |
// continued .... |
} |
} |
For some errors, you can attempt to do more than inform the user. For example, if you try to set an SSL security level on a socket connection but the remote host is not secure, the stream object will report an error. You can then release the old stream object and create a new one for a non-secure socket connection.
© 2004, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-05-06)