Search code examples
c#try-catchhttprequestusing-statement

C# "using" blocks and catching exceptions


I have this code:

using (var requestStream = request.GetRequestStream())
{
    byte[] data = Encoding.UTF8.GetBytes(xmlData);
    requestStream.Write(data, 0, data.Length);
}

If the request I'm making fails because the remote server is down, how do I catch the error?

Should I just expand out the using block to try-catch-finally, or is there a more elegant way this is done when using "using" blocks?

(I need to catch only server-being-down type errors this way - I need to show the client these errors happen because their server connection is inadequate, not because of bugs in our software or something).


Solution

  • There are definitely four options here:

    • Abandon using and just have a try/catch/finally:

      var requestStream = request.GetRequestStream();
      try
      {
          byte[] data = Encoding.UTF8.GetBytes(xmlData);
          requestStream.Write(data, 0, data.Length);
      }
      catch (IOException e) // Or whatever
      {
          // Whatever you want
      }
      finally
      {
          requestStream.Dispose();
      }
      
    • Put just a try/catch block inside the using block:

      using (var requestStream = request.GetRequestStream())
      {
          try
          {
              byte[] data = Encoding.UTF8.GetBytes(xmlData);
              requestStream.Write(data, 0, data.Length);
          }
          catch (IOException e) // Or whatever
          {
              // Whatever you want
          }
      }
      
    • The same as the second option, but with the try/catch outside the using block instead of inside. I don't think it makes much difference which you use, to be honest.

    • Catch the exception at a higher level anyway, e.g. in the calling method. Often this is a better approach, as you may well want to handle one type of exception from multiple "small" operations in the same way from the perspective of the "larger" operation.

    Personally I generally favour the second approach or the fourth. It's a consistent change: when I want to catch an exception, I introduce a try/catch block. The fact that it happens to be inside a using statement is neither here nor there. It ends up with more nesting, but I find it happens rarely enough that that's not a problem.