// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Properties;
namespace System.Web.Http.ExceptionHandling
{
/// Represents an unhandled exception logger.
public abstract class ExceptionLogger : IExceptionLogger
{
internal const string LoggedByKey = "MS_LoggedBy";
///
Task IExceptionLogger.LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
ExceptionContext exceptionContext = context.ExceptionContext;
Contract.Assert(exceptionContext != null);
if (!ShouldLog(context))
{
return TaskHelpers.Completed();
}
return LogAsync(context, cancellationToken);
}
/// When overridden in a derived class, logs the exception asynchronously.
/// The exception logger context.
/// The token to monitor for cancellation requests.
/// A task representing the asynchronous exception logging operation.
public virtual Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
{
Log(context);
return TaskHelpers.Completed();
}
/// When overridden in a derived class, logs the exception synchronously.
/// The exception logger context.
public virtual void Log(ExceptionLoggerContext context)
{
}
/// Determines whether the exception should be logged.
/// The exception logger context.
///
/// if the exception should be logged; otherwise, .
///
///
/// The default decision is only to log an exception instance the first time it is seen by this logger.
///
public virtual bool ShouldLog(ExceptionLoggerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
ExceptionContext exceptionContext = context.ExceptionContext;
Contract.Assert(exceptionContext != null);
IDictionary data = exceptionContext.Exception.Data;
if (data == null || data.IsReadOnly)
{
// If the exception doesn't have a mutable Data collection, we can't prevent duplicate logging. In this
// case, just log every time.
return true;
}
ICollection