Scenario:
I have a loop that iterates over an Array
of COM objects and does some work using them.
My fear, working with COM objects, is that some exception will creep up (possibly on another user's environment) and cause the loop to break mid-way through processing these objects.
So, let's say (hypothetically) an exception occurs on file 32 of 173.
I see three options:
Show the exception, inform the user that only 32 files were processed, and we then have to manually do the work on the remaining 141 files.
Undo all the work done on the first 32 files, inform the user the request couldn't be completed and show the exception. This is less than ideal because by the time we are at this procedure, a lot of up-front work has been done (creating files, incrementing serial numbers, etc.) which would be cumbersome and difficult to undo. In the end, we end up with all 172 files needing manual work.
Catch the exception, store it in a List, continue to try to process the rest of the files, then after trying to process all files, inform the user of any exceptions that occurred and any files which couldn't be processed. Best case we only have one file to manually do work on, and worst case we are left with 141 files - same as the first option.
Event horizon:
I'm new to programming. In fact I just wrote (am writing) my first add-in which I posted up on SE::Code Review.
Now, I'm of the mindset that option three makes the most sense - let's at least give hope a chance and see what happens with the rest of them, no?
So here's my implementation (well simplified, but this is the pattern):
Sub Main()
Dim Exceptions as New List(of Exception)
Try
TryThatFunkyCOMthing (Exceptions)
If Exceptions.Count>0 Then
For Each ex As Exception in Exceptions
MessageBox.Show(ex.ToString)
Next
End If
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
Private Sub TryThatFunkyCOMthing (ByRef ExceptionBuffer as List(of Exception))
For each COMthingy in COMthings
Try
COMthingy.DoSomething
Catch ex As SpecificException
COMthingy.WeAreBlewedUp
Catch ex As Exception
ExceptionBuffer.Add(ex)
End Try
Next
End Sub
One of the reviewers on CR gave me some feedback saying I should NOT be doing this. He said I should want the loop to stop if an exception occurs.
He linked to this SO Q&A regarding handling general exceptions, which I read (a few times now) and I think this solution falls under "failing gracefully". As mentioned above, I'm not trying to swallow exceptions, just control how/when they are handled so that my program behaves in a manner I can predict and depend on, even in the event of a catastrophic or unexpected exception.
What I'd like to know:
- If this is bad practice, why?
- Out of the three options I provided, which would you choose? - OR - Is there a mysterious and much better fourth option I'm missing?