Вопрос

I want to modify the Message property in Exception with additional info. For example the generated SQL from EF.

But I don't want to lose anything from the original Exception. This will make me lose the stacktrace:

catch (Exception ex)
{
    throw ex;
}

These Exception's are coming from the Data Layer. And I want to throw them so that they can be logged with Elmah.

What are my options?

Это было полезно?

Решение

If you want to add something you can just wrap it in another exception:

catch( Exception ex)
{
   throw new Exception("my new message",ex);
}

and you will be able to access the inside exception with the full stack trace

Другие советы

Define your custom exception class, and put the original exception as the inner exception, and throw the wrapped exception:

public class CustomException : Exception
{
    public CustomException()
        : base()
    {
    }

    public CustomException(string message)
        : base(message) 
    { 
    }

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

//...other constructors with parametrized messages for localization if needed
}

catch (Exception ex)
{
    throw new CustomException("Something went wrong", ex);
}

Of course its name should be changed accordingly. This way you have full control on exceptions used in your domain, and you don't loose any information from the original throw.

It is very helpful, especially in large projects, to have custom exceptions with good class names. They help in diagnosing problems from first sight in many simple situations, without the need of reading into exception's details and debugging. The latter is needed only when some really elaborate problems occurs. Thus, throwing around bare Exception instances wrapped around each other seems a bad practice.

The short answer to your question is, you can't. An exception is effectively a fault report and as such represents an historical event. Historical events by nature are immutable therefore you can't (nor should want to) "modify" them.

Instead what you can do is add some context to the exception by catching it and throwing a new exception. This will allow you to attach additional diagnostic information and also pass in the original exception thus maintaining the entire fault trail.

I won't go into detail on how to write a custom/use exception as I have already written a detailed answer on this subject before. However, as an example, your handling code should end up looking something like

catch (SomeEntityFrameworkException ex)
{
    throw new MyCustomException("Some additional info", ex);
}

I would just make my own exception that contains the original exception and any additional information you want, create the new exception in your catch block and throw it

Just do:

catch (Exception ex)
{
    throw;
}

This passes the exception further without re-throwing it, and preserves context.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top