Click here to Skip to main content
11,581,510 members (60,482 online)
Click here to Skip to main content

Testing disk space exceptions with CopyToAsync

, 2 Sep 2014 CPOL 2.6K
Rate this:
Please Sign up or sign in to vote.
I got an error report from the field in Upload to YouTube where the user was getting an unhandled exception when I copied their Camera Roll video to temporary storage to hand off to Movie Maker for editing. Great catch, now to shore up the UX when this happens. Only problem is, I need to […]Co

I got an error report from the field in Upload to YouTube where the user was getting an unhandled exception when I copied their Camera Roll video to temporary storage to hand off to Movie Maker for editing. Great catch, now to shore up the UX when this happens. Only problem is, I need to test filling up the disk during a copy. How could I possibly do this?

It was suggested that I simply write to the disk until it’s full. Yeah, if you’re testing filling up a disk that’s the way to do it. But what bout filling up the disk during a copy? Hmm… well, if I wanted to do this I basically need to create a source file that’s as big as it needs to be to fill the disk.

Enter EndlessReadStream Smile | :)

If you ever need to test this kind of scenario, hopefully this will come in handy for you as well!

   1: class EndlessReadStream : Stream
   2: {
   3:     public override bool CanRead
   4:     {
   5:         get { return true; }
   6:     }
   7:
   8:     public override bool CanSeek
   9:     {
  10:         get { return true; }
  11:     }
  12:
  13:     public override bool CanWrite
  14:     {
  15:         get { return false; }
  16:     }
  17:
  18:     public override void Flush()
  19:     {
  20:         return;
  21:     }
  22:
  23:     public override long Length
  24:     {
  25:         get { return long.MaxValue; }
  26:     }
  27:
  28:     public override long Position { get; set; }
  29:
  30:     public override int Read(byte[] buffer, int offset, int count)
  31:     {
  32:         for (int i = 0; i < count; i++)
  33:         {
  34:             buffer[offset + i] = 0;
  35:         }
  36:
  37:         return count;
  38:     }
  39:
  40:     public override long Seek(long offset, SeekOrigin origin)
  41:     {
  42:         return 0;
  43:     }
  44:
  45:     public override void SetLength(long value)
  46:     {
  47:         throw new InvalidOperationException();
  48:     }
  49:
  50:     public override void Write(byte[] buffer, int offset, int count)
  51:     {
  52:         throw new InvalidOperationException();
  53:     }
  54: }

usage:

   1: using (var outStream = await outFile.OpenStreamForWriteAsync())
   2: using (var inStream = new EndlessReadStream())
   3: {
   4:     try
   5:     {
   6:         await inStream.CopyToAsync(outStream);
   7:     }
   8:     catch (Exception ex)
   9:     {
  10:         if (ex.Message.Contains("80070070"))
  11:         {
  12:             // Out of disk space!
  13:         }
  14:     }
  15: }

I do wish the API would throw an IOException in this case, but it doesn’t so we have to trap it by looking specifically for the HResult code. Curious what the Exception does look like? Here’s the output from “Copy exception detail to clipboard”:

System.Exception was caught
  HResult=-2147024784
  Message=There is not enough space on the disk. (Exception from HRESULT: 0x80070070)
  Source=mscorlib
  StackTrace:
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
       at System.IO.BufferedStream.<WriteToUnderlyingStreamAsync>d__d.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.IO.Stream.<CopyToAsyncInternal>d__2.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
       at
<My code here> 
  InnerException:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

BC3Tech
Software Developer (Senior)
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150603.1 | Last Updated 2 Sep 2014
Article Copyright 2014 by BC3Tech
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid