//-----------------------------------------------------------------------
//
// 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
}
}