Red Gate forums :: View topic - Pattern for reporting exception and continuing
Return to www.red-gate.com RSS Feed Available

Search  | Usergroups |  Profile |  Messages |  Log in  Register 
Go to product documentation
SmartAssembly 6
SmartAssembly 6 forum

Pattern for reporting exception and continuing

Search in SmartAssembly 6 forum
Post new topic   Reply to topic
Jump to:  
Author Message
fostandy



Joined: 18 Apr 2011
Posts: 7

PostPosted: Tue May 03, 2011 3:06 am    Post subject: Pattern for reporting exception and continuing Reply with quote

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:
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:

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:

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)
Back to top
View user's profile Send private message
Brian Donahue



Joined: 23 Aug 2004
Posts: 6582

PostPosted: Wed May 04, 2011 10:24 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
fostandy



Joined: 18 Apr 2011
Posts: 7

PostPosted: Wed May 04, 2011 1:30 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
fostandy



Joined: 18 Apr 2011
Posts: 7

PostPosted: Thu May 05, 2011 6:20 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
Brian Donahue



Joined: 23 Aug 2004
Posts: 6582

PostPosted: Thu May 05, 2011 11:18 am    Post subject: Reply with quote

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?
Back to top
View user's profile Send private message
fostandy



Joined: 18 Apr 2011
Posts: 7

PostPosted: Tue May 10, 2011 5:08 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
Brian Donahue



Joined: 23 Aug 2004
Posts: 6582

PostPosted: Tue May 10, 2011 5:16 pm    Post subject: Reply with quote

Just set the TryToContinue property in OnReportException and that should do the job, as I understand.
Code:

   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;
      }
}
Back to top
View user's profile Send private message
fostandy



Joined: 18 Apr 2011
Posts: 7

PostPosted: Thu May 12, 2011 10:29 am    Post subject: Reply with quote

Ok, in my usercode i have this

Code:
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?
Back to top
View user's profile Send private message
Brian Donahue



Joined: 23 Aug 2004
Posts: 6582

PostPosted: Thu May 12, 2011 11:16 am    Post subject: Reply with quote

I've handled this in the past by declaring my own type of exception and checking the exception type in OnReportException.
Code:

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.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic All times are GMT + 1 Hour
Page 1 of 1

 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group