1

I need to log exception (even in release version) in my application. I am using a static method Log(Exception ex) of a class CLog to log the exception. I am also using Code Contracts and using both static and runtime checking. Please consider the following code:

public void editCommit(CEmployee emp)
    {
        Contract.Requires<ArgumentNullException>(null != emp, "Null argument, Parameter name : emp");
        this.employee.Name = emp.Name;
        this.employee.Age = emp.Age;
    }

Now If I don't correct all the warnings generated, how can I Log the exception ArgumentNullException thrown at runtime? I need to log the exception in same method. Please help.

Panjiyar Rahul
  • 1,180
  • 1
  • 13
  • 30
Anirban Paul
  • 1,065
  • 1
  • 16
  • 22
  • Why is the requirement to log it in the same method? Why not just collect it alongside all other unhandled exceptions in a top level exception handler? – Damien_The_Unbeliever Jan 17 '13 at 07:15

2 Answers2

2

Contract exceptions should be handled differently from ordinary exceptions, because a contract should specify a fact about your program that should be true 100% of the time, regardless of the state of the system. If a contract fails, it means that you almost certainly have a bug in your code. The Code Contracts team have provided another way of discovering failures which might be useful in this case (see section 7, "Runtime Contract Behavior" in the manual).

You have two options: you can either provide an event handler for the ContractFailedEvent (which is what I'd recommend in this case), or alternatively provide a complete replacement for the Contract Runtime class (see the manual for more details of this one).

The event handler should be registered as early as possible:

static void Main(string[] args)
{
    InitialiseContractHandler();
    //...
}

public static void InitialiseContractHandler()
{
    Contract.ContractFailed += (sender, eventArgs) =>
    {
        eventArgs.SetHandled();
        eventArgs.SetUnwind();                  
        MyContractFailureLogger(eventArgs);
        Assert.Fail(eventArgs.Message);
    };
}

The reason I'd use this pattern is so that you can also call the initialising method from an AssemblyInitializer method for unit testing purposes.

Setting the failure as handled this way will prevent the contract runtime from throwing exceptions itself, which is why I've included the Assert.Fail() - after all, you will still want execution to terminate.

  • I am following MVVM architecture to develop a WPF application. Can you please suggest me how to Log errors that are generated from 1> Contract Exceptions 2> Unhandled Exceptions ( in this case should we Handle and Log in DispatcherUnhandledException ??) 3> Exception in anothre thread – Anirban Paul Jan 17 '13 at 11:37
  • I don't work with WPF, so I can't help you there. If you want to know best practices for handling unhandled exceptions and cross-thread exceptions, or "how to log" in general (for instance, logging frameworks) you should raise those as separate questions. They're not really anything to do with Code Contracts. – Stephen J. Anderson Jan 17 '13 at 13:50
0

Catch the exception in the calling/ any upper level function?

Edit: The example

public void editCommit(CEmployee emp)
    {
        try
        {
           Contract.Requires<ArgumentNullException>(null != emp, "Null argument, Parameter name : emp");
           this.employee.Name = emp.Name;
           this.employee.Age = emp.Age;
         }
         catch( ArgumentNullException x )
         {
             System.Console.Error.WriteLine( "{0}: {1} @", typeof( x ).Name, x.Message );
             System.Console.Error.WriteLine( "{0}", x.StackTrace };
             //now throw the exception again so the caller can react to the error
             throw;
         }
    }

Of course you can use any other library to log your errors, I prefer log4net . If you write interactive programs, do not forget to inform the user that an action failed :-)

Mario The Spoon
  • 4,799
  • 1
  • 24
  • 36
  • I am actually trying to find out whether there is any way to catch the exception in the same method. – Anirban Paul Jan 17 '13 at 06:22
  • Also I would like to know is that correct way to Log the exceptions. I need to log all the exceptions even in release build. But I am also keen to use Code Contracts to minimize the bugs. Please suggest how can I combine both to get the best result. – Anirban Paul Jan 17 '13 at 06:27
  • The above code gives the following error "Error :Contract section within try block." – Anirban Paul Jan 17 '13 at 06:48
  • 1
    @AnirbanPaul - I think it's a lost cause. The only way to detect this failure is to catch the exception. But, as you've seen, contracts have to be the very first part of a method. So you **can not** detect this failure from within the same method. – Damien_The_Unbeliever Jan 17 '13 at 07:47
  • Sorry, I did not know that, since I usually do not catc it in the same function - at least not the code contracts exceptions – Mario The Spoon Jan 17 '13 at 08:25