e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
146 lines
4.8 KiB
C#
146 lines
4.8 KiB
C#
//-----------------------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel.Dispatcher
|
|
{
|
|
using System.Diagnostics;
|
|
using System.Runtime;
|
|
using System.Runtime.ConstrainedExecution;
|
|
using System.Security;
|
|
using System.Security.Permissions;
|
|
using System.ServiceModel;
|
|
|
|
public abstract class ExceptionHandler
|
|
{
|
|
static readonly ExceptionHandler alwaysHandle = new AlwaysHandleExceptionHandler();
|
|
|
|
static ExceptionHandler transportExceptionHandler = alwaysHandle;
|
|
|
|
public static ExceptionHandler AlwaysHandle
|
|
{
|
|
get
|
|
{
|
|
return alwaysHandle;
|
|
}
|
|
}
|
|
|
|
public static ExceptionHandler AsynchronousThreadExceptionHandler
|
|
{
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
get
|
|
{
|
|
//
|
|
HandlerWrapper wrapper = (HandlerWrapper)Fx.AsynchronousThreadExceptionHandler;
|
|
return wrapper == null ? null : wrapper.Handler;
|
|
}
|
|
|
|
[Fx.Tag.SecurityNote(Critical = "Calls a LinkDemanded method (Fx setter) and critical method (HandlerWrapper ctor)",
|
|
Safe = "protected with LinkDemand")]
|
|
[SecuritySafeCritical]
|
|
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
|
|
set
|
|
{
|
|
Fx.AsynchronousThreadExceptionHandler = value == null ? null : new HandlerWrapper(value);
|
|
}
|
|
}
|
|
|
|
public static ExceptionHandler TransportExceptionHandler
|
|
{
|
|
get
|
|
{
|
|
return transportExceptionHandler;
|
|
}
|
|
|
|
set
|
|
{
|
|
transportExceptionHandler = value;
|
|
}
|
|
}
|
|
|
|
// Returns true if the exception has been handled. If it returns false or
|
|
// throws a different exception, the original exception will be rethrown.
|
|
public abstract bool HandleException(Exception exception);
|
|
|
|
|
|
class AlwaysHandleExceptionHandler : ExceptionHandler
|
|
{
|
|
[Fx.Tag.SecurityNote(Miscellaneous = "this function can be called from within a CER, must not call into PT code")]
|
|
public override bool HandleException(Exception exception)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
internal static bool HandleTransportExceptionHelper(Exception exception)
|
|
{
|
|
if (exception == null)
|
|
{
|
|
throw Fx.AssertAndThrow("Null exception passed to HandleTransportExceptionHelper.");
|
|
}
|
|
|
|
ExceptionHandler handler = TransportExceptionHandler;
|
|
if (handler == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (!handler.HandleException(exception))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
catch (Exception thrownException)
|
|
{
|
|
if (Fx.IsFatal(thrownException))
|
|
{
|
|
throw;
|
|
}
|
|
|
|
DiagnosticUtility.TraceHandledException(thrownException, TraceEventType.Error);
|
|
return false;
|
|
}
|
|
|
|
DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);
|
|
return true;
|
|
}
|
|
|
|
|
|
class HandlerWrapper : Fx.ExceptionHandler
|
|
{
|
|
[Fx.Tag.SecurityNote(Critical = "Cannot let PT code alter the handler wrapped by this class.")]
|
|
[SecurityCritical]
|
|
readonly ExceptionHandler handler;
|
|
|
|
[Fx.Tag.SecurityNote(Critical = "Cannot let PT code alter the handler wrapped by this class.")]
|
|
[SecurityCritical]
|
|
public HandlerWrapper(ExceptionHandler handler)
|
|
{
|
|
Fx.Assert(handler != null, "Cannot wrap a null handler.");
|
|
this.handler = handler;
|
|
}
|
|
|
|
public ExceptionHandler Handler
|
|
{
|
|
[Fx.Tag.SecurityNote(Critical = "Access security-critical field.", Safe = "Ok to read field.")]
|
|
[SecuritySafeCritical]
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
get
|
|
{
|
|
return this.handler;
|
|
}
|
|
}
|
|
|
|
[Fx.Tag.SecurityNote(Critical = "Access security-critical field.", Safe = "Ok to call handler.",
|
|
Miscellaneous = "Called in a CER, must not call into PT code.")]
|
|
[SecuritySafeCritical]
|
|
public override bool HandleException(Exception exception)
|
|
{
|
|
return this.handler.HandleException(exception);
|
|
}
|
|
}
|
|
}
|
|
}
|