in Libraries/src/Amazon.Lambda.RuntimeSupport/ExceptionHandling/LambdaJsonExceptionWriter.cs [59:155]
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();
}