/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Amazon.Lambda.RuntimeSupport
{
///
/// Class to hold basic raw information extracted from Exceptions.
/// The raw information will be formatted as JSON to be reported to the Lambda Runtime API.
///
internal class ExceptionInfo
{
public string ErrorMessage { get; set; }
public string ErrorType { get; set; }
public StackFrameInfo[] StackFrames { get; set; }
public string StackTrace { get; set; }
public ExceptionInfo InnerException { get; set; }
public List InnerExceptions { get; internal set; } = new List();
public Exception OriginalException { get; set; }
public ExceptionInfo() { }
public ExceptionInfo(Exception exception, bool isNestedException = false)
{
if (exception == null)
throw new ArgumentNullException(nameof(exception));
ErrorType = exception.GetType().Name;
ErrorMessage = exception.Message;
if (!string.IsNullOrEmpty(exception.StackTrace))
{
StackTrace stackTrace = new StackTrace(exception, true);
StackTrace = stackTrace.ToString();
// Only extract the stack frames like this for the top-level exception
// This is used for Xray Exception serialization
if (isNestedException || stackTrace?.GetFrames() == null)
{
StackFrames = new StackFrameInfo[0];
}
else
{
StackFrames = (
from sf in stackTrace.GetFrames()
where sf != null
select new StackFrameInfo(sf)
).ToArray();
}
}
if (exception.InnerException != null)
{
InnerException = new ExceptionInfo(exception.InnerException, true);
}
AggregateException aggregateException = exception as AggregateException;
if (aggregateException != null && aggregateException.InnerExceptions != null)
{
foreach (var innerEx in aggregateException.InnerExceptions)
{
InnerExceptions.Add(new ExceptionInfo(innerEx, true));
}
}
}
public static ExceptionInfo GetExceptionInfo(Exception exception)
{
return new ExceptionInfo(exception);
}
}
}