I am writting an API for some data manipulation these days and I have faced a question that I cannot answer myself :D
I have made an exception class that extends the .net Application Exception class because I want to add some functionality there to be executed everytime the API throws an exception. For example I want to alert the error message and stacktrace via sms and email and I want to log the inner exception via Log4net. I don't know if this is a good aproach to use with the custom exception class or if I o开发者_如何学Goverused the meaning of the custom exceptions.
I have read this article about how to extend the Exception in c# so here we go with my example of code :
public class CustomExceptionClass : Exception
{
/// <summary>
/// I use custom functionality here everytime this exception occures
/// </summary>
/// <param name="errorMessage">error message</param>
/// <param name="innerEx">Inner exception that cause this exception</param>
public MyCustomException(string errorMessage, Exception innerEx) : base(errorMessage, innerEx)
{
//log exception
_log.ErrorFormat(errorMessage, innerEx);
//alert via sms and email
AlertMailer.SendAlertMessage(errorMessage, innerEx, innerEx.Message);
}
}
I think that doing logging and alerting by throwing a custom exception is a valid technique.
However, you shouldn't do the logging and alerting in the exception constructor. Instead you should catch the custom exception in all entry-points to your API and do the logging and alerting in the catch block. For example:
void MyApiFunction()
{
try
{
// do data manipulation
}
catch(MyCustomException ex)
{
_log.ErrorFormat(ex.ErrorMessage, ex.InnerEx);
AlertMailer.SendAlertMessage(ex.ErrorMessage, ex.InnerEx);
}
}
I would recomend you to use AOP instead.
PostSharp exception handling
Custom exceptions should be used to define different types of exception.
- Exceptions from the database
- Exceptions from file io
- Exceptions from web services
They should be very simple, and contain no other logic than assigning variables. Why? Because if the exception constructor throws another exception you are going to have a hard time tracing it.
The ways i handle those exceptions are:
- AOP (Spring.NET)
- Specific try/catches
- The global exception handler
In a program
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
try {
//do something
} catch(Exception e) {
//log error
}
}
}
}
Or in a web site
public class ApplicationErrorModule : IHttpModule {
public void Init(HttpApplication context) {
context.Error += new EventHandler(context_Error);
}
private void context_Error(object sender, EventArgs e) {
//log error
}
}
Heavy treatments like logging and sending an email don't belong in the constructor of the exception. You should instead handle the exception using AOP as @petro suggested, or in a catch statement.
精彩评论