Unable to access StackTrace in custom C# Exception

I recently tried setting up a logging system for my Web API. I decided that I wanted to create custom Exception classes that could be thrown and then logged by my GlobalExceptionHandler. However, I am having some issues accessing the StackTrace of my custom Exception objects.

I set up a custom Exception class called LoggableException which I use as a parent class for all of my custom Exceptions that I want to log to my database.

    public class LoggableException : Exception
    {
        public LogEntity Log { get; set; }
        public string ResponseMessage { get; set; }

        public LoggableException(LogEntity _log, string _responseMessage) : base(_log.ExceptionMessage)
        {
            Log = _log;
            Log.Level = LogLevel.Warn;
            Log.Exception = GetType().Name;
            Log.StackTrace = StackTrace.Substring(0, 1000);

            ResponseMessage = _responseMessage;
        }
    }

Here is an example of one of my custom LoggableExceptions:

    public class InvalidPassword : LoggableException
    {
        public InvalidPassword(string email) : base(new LogEntity()
        {
            ExceptionMessage = $"Invalid password. email: {email}",
            ResponseCode = (int) HttpStatusCode.Unauthorized
        }, $"Unknown email or incorrect password.")
        { }
    }

However, it seems that whenever I throw one of these LoggableExceptions, a <System.NullReferenceException: Object reference not set to an instance of an object. is also thrown at Log.StackTrace = StackTrace.Substring(0, 1000);. I’m doing this so that I don’t store huge StackTrace strings in my database, but StackTrace is always null. I assumed that if I called the base constructor that it would automatically instantiate StackTrace, but I guess I was wrong. Can anyone explain to me what I am doing wrong here? I am still relatively new to C#.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The NullReference exception is thrown because you are accesing the StackTrace property of the instance you are building inside the constructor itself.

You should use

 Log.StackTrace = StackTrace?.Substring(0, 1000);

or

 if(StackTrace!=null) Log.StackTrace=StackTrace.Substring(0, 1000);

instead to be sure that this.StackTrace is already instantiated

You should take care from the ArgumentOutOfRangeException that can be thrown when StackTrace length is lesser than 1000 characters

Method 2

This is quite old, but there was no actual solution posted yet. I also wanted to automatically create a system log on each new custom exception (even if it’s not “best practice”), this is what worked for me.

Although the Stacktrace ain’t yet initialised in your constructor, you can create a new instance of StackTrace.

public class LoggableException : Exception
{
    public LogEntity Log { get; set; }
    public string ResponseMessage { get; set; }

    public LoggableException(LogEntity _log, string _responseMessage) : base(_log.ExceptionMessage)
    {
        Log = _log;
        Log.Level = LogLevel.Warn;
        Log.Exception = GetType().Name;
        Log.StackTrace = (new System.Diagnostics.StackTrace()).ToString();
        if (Log.StackTrace.Length > 1000)
            Log.StackTrace = Log.StackTrace.Substring(0, 1000);

        ResponseMessage = _responseMessage;
    }
}

This should do what you want.

The only problem is that your LoggableException constructor will also jerk its way in there (Frame zero), but you can always loop all frames to create your Stactrace String, formating the data as you want and skipping frame zero.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x