private static string GetStackTraceJson(string stackTrace, int tab) { if (stackTrace == null) { return(null); } string[] stackTraceElements = stackTrace.Split(new[] { Environment.NewLine }, StringSplitOptions.None) .Select(s => s.Trim()) .Where(s => !String.IsNullOrWhiteSpace(s)) .Select(s => TabString(($"\"{JsonExceptionWriterHelpers.EscapeStringForJson(s)}\""), tab + 1)) .ToArray(); if (stackTraceElements.Length == 0) { return(null); } StringBuilder stackTraceBuilder = new StringBuilder(); stackTraceBuilder.AppendLine(TabString($"\"{STACK_TRACE}\": [", tab)); stackTraceBuilder.AppendLine(string.Join("," + Environment.NewLine, stackTraceElements)); stackTraceBuilder.Append(TabString("]", tab)); return(stackTraceBuilder.ToString()); }
public static string WriteJson(ExceptionInfo ex) { string workingDir = JsonExceptionWriterHelpers.EscapeStringForJson(System.IO.Directory.GetCurrentDirectory()); string exceptionTxt = CreateExceptionJson(ex, 1); string workingDirJson = TabString($"\"{WORKING_DIR}\": \"{workingDir}\"", 1); string exceptionJson = TabString($"\"{EXCEPTION}\": [ {exceptionTxt} ]", 1); var paths = new string[0]; // Build the paths list by getting all the unique file names in the stack trace elements if (ex.StackFrames != null) { paths = ( from sf in ex.StackFrames where sf.Path != null select "\"" + JsonExceptionWriterHelpers.EscapeStringForJson(sf.Path) + "\"" ).Distinct().ToArray(); } StringBuilder pathsBuilder = new StringBuilder(); pathsBuilder.Append(TabString($"\"{PATHS}\": ", 1)); pathsBuilder.Append(CombinePartsIntoJsonObject(2, '[', ']', paths)); string pathsJson = pathsBuilder.ToString(); // Add each non-null element to the json elements list string[] jsonElements = GetNonNullElements(workingDirJson, exceptionJson, pathsJson); return(CombinePartsIntoJsonObject(1, '{', '}', jsonElements.ToArray())); }
// Craft JSON object {...} for a particular stack frame private static string CreateStackFrameJson(StackFrameInfo stackFrame, int tab) { string file = JsonExceptionWriterHelpers.EscapeStringForJson(stackFrame.Path); string label = JsonExceptionWriterHelpers.EscapeStringForJson(stackFrame.Label); int line = stackFrame.Line; string fileJson = null; string lineJson = null; if (file != null) { fileJson = TabString($"\"{STACK_FRAME_FILE}\": \"{file}\"", tab); lineJson = TabString($"\"{STACK_FRAME_LINE}\": {line}", tab); } string labelJson = null; if (label != null) { labelJson = TabString($"\"{STACK_FRAME_METHOD}\": \"{label}\"", tab); } string[] jsonElements = GetNonNullElements(fileJson, labelJson, lineJson); return(CombinePartsIntoJsonObject(tab, '{', '}', jsonElements)); }
private static string CreateExceptionJson(ExceptionInfo ex, int tab) { // Grab the elements we want to capture string message = JsonExceptionWriterHelpers.EscapeStringForJson(ex.ErrorMessage); string type = JsonExceptionWriterHelpers.EscapeStringForJson(ex.ErrorType); var stackTrace = ex.StackFrames; // Create the JSON lines for each non-null element string messageJson = null; if (message != null) { // Trim important for Aggregate Exceptions, whose // message contains multiple lines by default messageJson = TabString($"\"{ERROR_MESSAGE}\": \"{message}\"", tab + 1); } string typeJson = TabString($"\"{ERROR_TYPE}\": \"{type}\"", tab + 1); string stackTraceJson = GetStackTraceJson(stackTrace, tab + 1); // Add each non-null element to the json elements list string[] jsonElements = GetNonNullElements(typeJson, messageJson, stackTraceJson); return(CombinePartsIntoJsonObject(tab + 1, '{', '}', jsonElements)); }
private static string AppendJson(ExceptionInfo ex, int tab, bool appendComma, int remainingRoom) { if (remainingRoom <= 0) { return(null); } MeteredStringBuilder jsonBuilder = new MeteredStringBuilder(TEXT_ENCODING, remainingRoom); int nextTabDepth = tab + 1; int nextNextTabDepth = nextTabDepth + 1; List <string> jsonElements = new List <string>(); // Grab the elements we want to capture string message = JsonExceptionWriterHelpers.EscapeStringForJson(ex.ErrorMessage); string type = JsonExceptionWriterHelpers.EscapeStringForJson(ex.ErrorType); string stackTrace = ex.StackTrace; ExceptionInfo innerException = ex.InnerException; List <ExceptionInfo> innerExceptions = ex.InnerExceptions; // Create the JSON lines for each non-null element string messageJson = null; if (message != null) { // Trim important for Aggregate Exceptions, whose // message contains multiple lines by default messageJson = TabString($"\"{ERROR_MESSAGE}\": \"{message}\"", nextTabDepth); } string typeJson = TabString($"\"{ERROR_TYPE}\": \"{type}\"", nextTabDepth); string stackTraceJson = GetStackTraceJson(stackTrace, nextTabDepth); // Add each non-null element to the json elements list if (typeJson != null) { jsonElements.Add(typeJson); } if (messageJson != null) { jsonElements.Add(messageJson); } if (stackTraceJson != null) { jsonElements.Add(stackTraceJson); } // Exception JSON body, comma delimited string exceptionJsonBody = string.Join("," + Environment.NewLine, jsonElements); jsonBuilder.AppendLine(TabString("{", tab)); jsonBuilder.Append(exceptionJsonBody); bool hasInnerException = innerException != null; bool hasInnerExceptionList = innerExceptions != null && innerExceptions.Count > 0; // Before we close, check for inner exception(s) if (hasInnerException) { // We have to add the inner exception, which means we need // another comma after the exception json body jsonBuilder.AppendLine(","); jsonBuilder.Append(TabString($"\"{INNER_EXCEPTION}\": ", nextTabDepth)); string innerJson = AppendJson(innerException, nextTabDepth, hasInnerExceptionList, remainingRoom - jsonBuilder.SizeInBytes); if (innerJson != null && jsonBuilder.HasRoomForString(innerJson)) { jsonBuilder.Append(innerJson); } else { jsonBuilder.AppendLine(TRUNCATED_MESSAGE); } } if (hasInnerExceptionList) { jsonBuilder.Append(TabString($"\"{INNER_EXCEPTIONS}\": [", nextTabDepth)); for (int i = 0; i < innerExceptions.Count; i++) { var isLastOne = i == innerExceptions.Count - 1; var innerException2 = innerExceptions[i]; string innerJson = AppendJson(innerException2, nextNextTabDepth, !isLastOne, remainingRoom - jsonBuilder.SizeInBytes); if (innerJson != null && jsonBuilder.HasRoomForString(innerJson)) { jsonBuilder.Append(innerJson); } else { jsonBuilder.AppendLine(TabString(TRUNCATED_MESSAGE, nextNextTabDepth)); break; } } jsonBuilder.AppendLine(TabString($"]", nextTabDepth)); } if (!hasInnerException && !hasInnerExceptionList) { // No inner exceptions = no trailing comma needed jsonBuilder.AppendLine(); } jsonBuilder.AppendLine(TabString("}" + (appendComma ? "," : ""), tab)); return(jsonBuilder.ToString()); }