How can I make this call to log my exceptions recursive?
-
10-06-2021 - |
Pregunta
I have the following code:
protected string formatException(Exception e)
{
var exError = "<form>";
if (e == null)
{
throw new ArgumentNullException("e");
}
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse message</span>" +
"<span class='show-collapsed'>expand message</span>" +
"</a></legend><p>" + e.Message + "</p></fieldset>";
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse trace</span>" +
"<span class='show-collapsed'>expand trace</span>" +
"</a></legend><p>" + e.StackTrace + "</p></fieldset>";
if (e.InnerException != null)
{
// same functionality but for the inner exception and the InnerException.InnerException
}
return exError + "</form>";
}
When called it formats the exception message. However I would like to make it include the InnerException
and the InnerException.InnerException
Is there some way I could do this recursively or would it be better to put the message format in another function and call that?
Solución
Here's what I'd do:
protected string formatException(Exception e)
{
Func<string, string> createFieldSet =
t =>
"<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse message</span>" +
"<span class='show-collapsed'>expand message</span>" +
"</a></legend><p>" + t + "</p></fieldset>";
var exError = new StringBuilder("<form>");
if (e == null)
{
throw new ArgumentNullException("e");
}
while (e != null)
{
exError.AppendLine(createFieldSet(e.Message));
exError.AppendLine(createFieldSet(e.StackTrace));
e = e.InnerException;
}
exError.AppendLine("</form>");
return exError.ToString();
}
Otros consejos
I know this is an old question and that there is already a marked answer. However, this is how I do it and I'll post this here in case it helps someone:
public static class ExceptionExtension
{
public static string GetFullTrace(this Exception ex, bool recursive = true)
{
string trace = "";
trace += "Name: " + ex.GetType().Name + "\n";
trace += "Message: " + ex.Message + "\n";
trace += "Stack Trace: " + (ex.StackTrace ?? "null") + "\n";
if (recursive)
{
while (ex.InnerException != null)
{
ex = ex.InnerException;
trace += "\n-------------------- Caused by: --------------------\n";
trace += "Name: " + ex.GetType().Name + "\n";
trace += "Message: " + ex.Message + "\n";
trace += "Stack Trace: " + (ex.StackTrace ?? "null") + "\n";
}
}
return trace;
}
}
A slight change from previous answers is to use an extension method. This way one can simply call it as:
try
{
SomeOperationWhichMayThrow();
}
catch(Exception ex)
{
LogError(ex.GetFullTrace());
}
I have a project which contains many reusable utilities and extension methods, which I include in most of my projects. ExceptionExtension
is one of those utils.
For better performance, consider using a StringBuilder
instead.
Try using something like
Exception ex = e;
while (ex != null)
{
string s = ex.Message;
ex = ex.InnerException;
}
I would do it like this:
private string privateFormatException(Exception e)
{
var exError = String.Empty;
if (e == null)
{
return exError;
}
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse message</span>" +
"<span class='show-collapsed'>expand message</span>" +
"</a></legend><p>" + e.Message + "</p></fieldset>";
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse trace</span>" +
"<span class='show-collapsed'>expand trace</span>" +
"</a></legend><p>" + e.StackTrace + "</p></fieldset>";
return exError + privateFormatException(e.InnerException);
}
protected string formatException(Exception e)
{
var exError = "<form>";
if (e == null)
{
throw new ArgumentNullException("e");
}
exError += privateFormatException(e);
return exError + "</form>";
}
I'm not sure if the follow code could solve it. It may need some format.
protected string formatException(Exception e)
{
var exError = "<form>";
if (e == null)
{
throw new ArgumentNullException("e");
}
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse message</span>" +
"<span class='show-collapsed'>expand message</span>" +
"</a></legend><p>" + e.Message + "</p></fieldset>";
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse trace</span>" +
"<span class='show-collapsed'>expand trace</span>" +
"</a></legend><p>" + e.StackTrace + "</p></fieldset>";
if (e.InnerException != null)
{
exError += formatException(e.InnerException);
}
return exError + "</form>";
}
EDIT
protected string FormatException(Exception e)
{
if (e == null)
{
throw new ArgumentNullException("e");
}
var exError = "<form>";
exError += FormatExceptionInternal(e);
return exError + "</form>";
}
private string FormatExceptionInternal(Exception e)
{
var exError = "";
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse message</span>" +
"<span class='show-collapsed'>expand message</span>" +
"</a></legend><p>" + e.Message + "</p></fieldset>";
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse trace</span>" +
"<span class='show-collapsed'>expand trace</span>" +
"</a></legend><p>" + e.StackTrace + "</p></fieldset>";
if (e.InnerException != null)
{
exError += FormatExceptionInternal(e.InnerException);
}
return exError;
}
Your FormatException method should be like that, do not need to declare exError variable as class level, declare it in the function and just return..
protected string formatException(Exception e)
{
var exError = string.Empty;
if (e == null)
{
throw new ArgumentNullException("e");
}
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse message</span>" +
"<span class='show-collapsed'>expand message</span>" +
"</a></legend><p>" + e.Message + "</p></fieldset>";
exError += "<fieldset><legend><a href='#'>" +
"<span class='show-expanded'>collapse trace</span>" +
"<span class='show-collapsed'>expand trace</span>" +
"</a></legend><p>" + e.StackTrace + "</p></fieldset>";
if (e.InnerException != null)
{
exError += formatException(e.InnerException);
}
return exError;
}
You can call this function like that and i hope so it will work for recursive as well.. Using of above method is
StringBuilder sb = new StringBuilder();
sb.Append("<form>");
sb.Append(formatException(new Exception()));// pass your own exception
sb.Append("</form>");
string strException = sb.ToString();
In your case pass your own exception...