10

I am doing some exception handling for code which is writing to the StandardInput stream of a Process object. The Process is kind of like the unix head command; it reads only part of it's input stream. When the process dies, the writing thread fails with:

IOException
The pipe has been ended. (Exception from HRESULT: 0x8007006D)

I would like to catch this exception and let it fail gracefully, since this is expected behavior. However, it's not obvious to me how this can robustly be distinguished from other IOExceptions. I could use message, but it's my understanding that these are localized and thus this might not work on all platforms. I could also use HRESULT, but I can't find any documentation that specifies that this HRESULT applies only to this particular error. What is the best way of doing this?

ChaseMedallion
  • 20,860
  • 17
  • 88
  • 152
  • What is the type of the stream you're trying to write to? Could you possibly query the stream to see if it is closed and if so fail silently? – Jim Mischel Jul 22 '14 at 00:06
  • 1
    Don't you know which code is running when the exception is seen? Put a try/catch around that specific code, then handle whichever exception you receive. – John Saunders Jul 22 '14 at 00:39
  • @JohnSaunders the problem is that I can't distinguish one type of IOException from another. I know where to put the try-catch, but not how to distinguish the right exception in the catch – ChaseMedallion Jul 22 '14 at 01:05
  • How many different IOExceptions occur while calling the one method that receives this exception? In any case, if you put the try/catch _immediately_ around the one line that receives the exception, and if you include catch blocks for exceptions derived from `IOException`, then you'll simply have to ignore all the remaining cases of `IOException`. – John Saunders Jul 22 '14 at 01:11
  • 1
    @JohnSaunders: I honestly don't know how many different types of IOExceptions could occur. It seems like any number of things could go wrong when trying to write to a redirected standard input stream. – ChaseMedallion Jul 22 '14 at 01:13
  • True, but you'll have to ignore all of them. Maybe log them first. – John Saunders Jul 22 '14 at 01:25

1 Answers1

5

Use Marshal.GetHRForException() to detect the error code for the IOException. Some sample code to help you fight the compiler:

using System;
using System.IO;
using System.Runtime.InteropServices;

class Program {
    static void Main(string[] args) {
        try {
            throw new IOException("test", unchecked((int)0x8007006d));
        }
        catch (IOException ex) {
            if (Marshal.GetHRForException(ex) != unchecked((int)0x8007006d)) throw;
        }
    }
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536