//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOAuth.Messaging { using System; using System.Collections.Generic; /// /// An exception to represent errors in the local or remote implementation of the protocol. /// [Serializable] public class ProtocolException : Exception, IDirectedProtocolMessage { /// /// The request message being processed when this exception was generated, if any. /// private IProtocolMessage inResponseTo; /// /// The indirect message receiver this exception should be delivered to, if any. /// private Uri recipient; /// /// A cache for extra name/value pairs tacked on as data when this exception is sent as a message. /// private Dictionary extraData = new Dictionary(); /// /// Initializes a new instance of the class. /// public ProtocolException() { } /// /// Initializes a new instance of the class. /// /// A message describing the specific error the occurred or was detected. public ProtocolException(string message) : base(message) { } /// /// Initializes a new instance of the class. /// /// A message describing the specific error the occurred or was detected. /// The inner exception to include. public ProtocolException(string message, Exception inner) : base(message, inner) { } /// /// Initializes a new instance of the class /// such that it can be sent as a protocol message response to a remote caller. /// /// The human-readable exception message. /// The message that was the cause of the exception. May not be null. internal ProtocolException(string message, IProtocolMessage faultedMessage) : base(message) { if (faultedMessage == null) { throw new ArgumentNullException("faultedMessage"); } this.FaultedMessage = faultedMessage; } /// /// Initializes a new instance of the class /// such that it can be sent as a protocol message response to a remote caller. /// /// The human-readable exception message. /// /// If is a response to an incoming message, this is the incoming message. /// This is useful for error scenarios in deciding just how to send the response message. /// May be null. /// /// /// In the case of exceptions that will be sent as indirect messages to the original calling /// remote party, this is the URI of that remote site's receiver. /// May be null only if the message is a direct request. /// internal ProtocolException(string message, IProtocolMessage inResponseTo, Uri remoteIndirectReceiver) : this(message) { if (inResponseTo == null) { throw new ArgumentNullException("inResponseTo"); } this.inResponseTo = inResponseTo; this.FaultedMessage = inResponseTo; if (remoteIndirectReceiver == null && inResponseTo.Transport != MessageTransport.Direct) { // throw an exception, with ourselves as the inner exception (as fully initialized as we can be). throw new ArgumentNullException("remoteIndirectReceiver"); } this.recipient = remoteIndirectReceiver; } /// /// Initializes a new instance of the class. /// /// The /// that holds the serialized object data about the exception being thrown. /// The System.Runtime.Serialization.StreamingContext /// that contains contextual information about the source or destination. protected ProtocolException( System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } #region IDirectedProtocolMessage Members /// /// Gets the URL of the intended receiver of this message. /// /// /// This property should only be called when the error is being sent as an indirect response. /// Uri IDirectedProtocolMessage.Recipient { get { if (this.inResponseTo == null) { throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit); } return this.recipient; } } #endregion #region IProtocolMessage Properties /// /// Gets the version of the protocol this message is prepared to implement. /// Version IProtocolMessage.ProtocolVersion { get { if (this.inResponseTo == null) { throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit); } return this.inResponseTo.ProtocolVersion; } } /// /// Gets the level of protection this exception requires when transmitted as a message. /// MessageProtection IProtocolMessage.RequiredProtection { get { return MessageProtection.None; } } /// /// Gets whether this is a direct or indirect message. /// MessageTransport IProtocolMessage.Transport { get { if (this.inResponseTo == null) { throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit); } return this.inResponseTo.Transport; } } /// /// Gets the dictionary of additional name/value fields tacked on to this message. /// IDictionary IProtocolMessage.ExtraData { get { return this.extraData; } } #endregion /// /// Gets the message that caused the exception. /// internal IProtocolMessage FaultedMessage { get; private set; } #region IProtocolMessage Methods /// /// See . /// void IProtocolMessage.EnsureValidMessage() { if (this.inResponseTo == null) { throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit); } } #endregion } }