1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
//-----------------------------------------------------------------------------
// 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);
}
}
}
}
|