问题
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.
回答1:
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.
回答2:
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 :-)
来源:https://stackoverflow.com/questions/14373156/how-to-log-error-while-using-code-contracts