Handling Stream Errors

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:

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