Pattern for reporting exception and continuing

.NET obfuscator and automated error reporting

Moderators: Luke Jefferson, melvyn.harbour, dom.smith

Pattern for reporting exception and continuing

Postby fostandy » Tue May 03, 2011 3:06 am

There are some circumstances when we want to catch an exception and do some other handling before dispatching it to our custom handler (which brings up a custom form and sends the report).

In addition, I don't want to bring our program to a crashing halt (we are able to gracefully recover from this exception).

Code: Select all
private void FooImpl()
{
   throw new Exception("failed");
}

public void Foo()
{
   try
   {
      FooImpl();
   }
   catch (Exception ex)
   {
      DoCleanup();
     Log(ex);
     ExceptionReporting.Report(ex);
   }
}

I noticed that in its current inception. Foo() will attempt to terminate the program, which is not what I want. Obviously I can then add code to my OnReportException(ReportExceptionEventArgs e) handler to set e.TryToContinue to true.

But my question is what is the best way to relay whether or not I want to continue to the handler? (Ideally, I guess I'd like a function like ExceptionReporting.Report(Exception ex, bool tryToContinue))

The most obvious solution to me is to create a

Code: Select all
public class CustomException : Exception
{
        public CustomException(string message) : base(message)
        {
        }

        public CustomException(string message, Exception innerException) : base(message, innerException)
        {
        }

        protected CustomException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }

        public bool TryToContinue { get; set; }

        public CustomException()
        {
        }
    }
}


My catch block in Foo() then becomes
Code: Select all
catch (Exception ex)
   {
     DoCleanup();
     Log(ex);
     ExceptionReporting.Report(new CustomException("", ex));
   }


And my OnReportException can interrogate the ReportExceptionEventArgs to see if it is of type CustomException and behave as necessary.

I've tested this, and it works, but it kind of smells to me to use an exception for this sort of message passing*. Just wondering if there is a better way?


(* In addition our smartassembly supported applications actually abstract out the error reporting functionality into a exception library, so referencing CustomException from both our UnhandledExceptionHandler and our exception library is a bit funny - but this is not major)
fostandy
 
Posts: 7
Joined: Mon Apr 18, 2011 5:37 am

Postby Brian Donahue » Wed May 04, 2011 10:24 am

Can you just catch and handle the exception in your code, then just throw it again? That should send it down to the SmartAssembly unhandled exception handler the same as if it was never caught, as far as I know.
Brian Donahue
 
Posts: 6670
Joined: Mon Aug 23, 2004 10:48 am

Postby fostandy » Wed May 04, 2011 1:30 pm

I realised I was thinking about this in completely the wrong way. Whatever code I had in my OnReportException(ReportExceptionEventArgs e) handler is what I should be putting into my catch brace - thanks.
fostandy
 
Posts: 7
Joined: Mon Apr 18, 2011 5:37 am

Postby fostandy » Thu May 05, 2011 6:20 am

actually I can't - no way to actually send an exception report from outside of the OnReportException handler.

Brian: My question was basically what should I put in my catch (Exception e) {} block to be able to set ReportExceptionEventArgs#TryToContinue = true; ?

I'm not seeing an immediate way to deal with this except either with static variables or wrapping the exception. The latter is the cleanest solution I can think of but it is still not particularly elegant.

This is more of a design question than a technical smartassembly question, although I do want to make sure I'm not missing something obvious in the API.
fostandy
 
Posts: 7
Joined: Mon Apr 18, 2011 5:37 am

Postby Brian Donahue » Thu May 05, 2011 11:18 am

I don't understand. If you have caught the exception yourself, you don't need to "try to continue" as you have handled the exception and can continue?
Brian Donahue
 
Posts: 6670
Joined: Mon Aug 23, 2004 10:48 am

Postby fostandy » Tue May 10, 2011 5:08 pm

I want to report the exception, and then continue.

I don't see how I can report the exception without re-throwing it for SmartAssembly to handle via the OnReportException method. And once rethrown I don't see any way to control the continue parameters short of wrapping it in a customized exception.
fostandy
 
Posts: 7
Joined: Mon Apr 18, 2011 5:37 am

Postby Brian Donahue » Tue May 10, 2011 5:16 pm

Just set the TryToContinue property in OnReportException and that should do the job, as I understand.
Code: Select all
   public class UnhandledExceptionHandlerWithoutUI : UnhandledExceptionHandler
   {
protected override void OnReportException(ReportExceptionEventArgs e)
      {
                                      //Put your custom exception form logic here
         for (int i=0; i<3; i++)
         {
            if (e.SendReport()) break;
         }
         e.TryToContinue = true;
      }
}
Brian Donahue
 
Posts: 6670
Joined: Mon Aug 23, 2004 10:48 am

Postby fostandy » Thu May 12, 2011 10:29 am

Ok, in my usercode i have this

Code: Select all
public void Foo()
{
    // here I would like to throw an exception and continue
   throw new Exception("I want this to report, but continue");
}

public void Foo2()
{
   throw new Exception("I want this to report, and not continue");
}

public class UnhandledExceptionHandlerWithoutUI : UnhandledExceptionHandler
   {
protected override void OnReportException(ReportExceptionEventArgs e)
      {
           // handle/report it

           if (/* WHAT GOES HERE? */)
              e.TryToContinue = false;
           else
              e.TryToContinue = true;
        }
}


My question is, what goes into the /* WHAT GOES HERE? */ that will make calls to Foo() and Foo2() behave as I desire?
fostandy
 
Posts: 7
Joined: Mon Apr 18, 2011 5:37 am

Postby Brian Donahue » Thu May 12, 2011 11:16 am

I've handled this in the past by declaring my own type of exception and checking the exception type in OnReportException.
Code: Select all
try{/*something*/}
catch (Exception e){
throw new ReportOnlyException("I only want to report this");
}
...
 protected override void OnReportException(ReportExceptionEventArgs e)
        {
            if (e.Exception is ReportOnlyException)
            e.TryToContinue=true;
            else e.TryToContinue=false;
         }

I guess you could also set something in the exception's Data property and check that.
Brian Donahue
 
Posts: 6670
Joined: Mon Aug 23, 2004 10:48 am


Return to SmartAssembly 6

Who is online

Users browsing this forum: zwestfall and 1 guest