summaryrefslogtreecommitdiffstats
path: root/src/DotNetOAuth/Messaging/ProtocolException.cs
blob: 10cb884b84a9a4d1ea59acf05a43a498a228d878 (plain)
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
//-----------------------------------------------------------------------
// <copyright file="ProtocolException.cs" company="Andrew Arnott">
//     Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOAuth.Messaging {
	using System;

	/// <summary>
	/// An exception to represent errors in the local or remote implementation of the protocol.
	/// </summary>
	[Serializable]
	public class ProtocolException : Exception, IDirectedProtocolMessage {
		/// <summary>
		/// The request message being processed when this exception was generated, if any.
		/// </summary>
		private IProtocolMessage inResponseTo;

		/// <summary>
		/// The indirect message receiver this exception should be delivered to, if any.
		/// </summary>
		private Uri recipient;

		/// <summary>
		/// Initializes a new instance of the <see cref="ProtocolException"/> class.
		/// </summary>
		public ProtocolException() { }

		/// <summary>
		/// Initializes a new instance of the <see cref="ProtocolException"/> class.
		/// </summary>
		/// <param name="message">A message describing the specific error the occurred or was detected.</param>
		public ProtocolException(string message) : base(message) { }

		/// <summary>
		/// Initializes a new instance of the <see cref="ProtocolException"/> class.
		/// </summary>
		/// <param name="message">A message describing the specific error the occurred or was detected.</param>
		/// <param name="inner">The inner exception to include.</param>
		public ProtocolException(string message, Exception inner) : base(message, inner) { }

		/// <summary>
		/// Initializes a new instance of the <see cref="ProtocolException"/> class
		/// such that it can be sent as a protocol message response to a remote caller.
		/// </summary>
		/// <param name="message">The human-readable exception message.</param>
		/// <param name="inResponseTo">
		/// If <paramref name="message"/> 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.
		/// </param>
		/// <param name="remoteIndirectReceiver">
		/// 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 <paramref name="inResponseTo"/> message is a direct request.
		/// </param>
		internal ProtocolException(string message, IProtocolMessage inResponseTo, Uri remoteIndirectReceiver)
			: this(message) {
			if (inResponseTo == null) {
				throw new ArgumentNullException("inResponseTo");
			}
			this.inResponseTo = 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;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ProtocolException"/> class.
		/// </summary>
		/// <param name="info">The <see cref="System.Runtime.Serialization.SerializationInfo"/> 
		/// that holds the serialized object data about the exception being thrown.</param>
		/// <param name="context">The System.Runtime.Serialization.StreamingContext 
		/// that contains contextual information about the source or destination.</param>
		protected ProtocolException(
		  System.Runtime.Serialization.SerializationInfo info,
		  System.Runtime.Serialization.StreamingContext context)
			: base(info, context) { }

		#region IDirectedProtocolMessage Members

		/// <summary>
		/// Gets the URL of the intended receiver of this message.
		/// </summary>
		/// <remarks>
		/// This property should only be called when the error is being sent as an indirect response.
		/// </remarks>
		Uri IDirectedProtocolMessage.Recipient {
			get { return this.recipient; }
		}

		#endregion

		#region IProtocolMessage Members

		/// <summary>
		/// Gets the version of the protocol this message is prepared to implement.
		/// </summary>
		Protocol IProtocolMessage.Protocol {
			get {
				if (this.inResponseTo == null) {
					throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit);
				}
				return this.inResponseTo.Protocol;
			}
		}

		/// <summary>
		/// Gets whether this is a direct or indirect message.
		/// </summary>
		MessageTransport IProtocolMessage.Transport {
			get {
				if (this.inResponseTo == null) {
					throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit);
				}
				return this.inResponseTo.Transport;
			}
		}

		/// <summary>
		/// See <see cref="IProtocolMessage.EnsureValidMessage"/>.
		/// </summary>
		void IProtocolMessage.EnsureValidMessage() {
			if (this.inResponseTo == null) {
				throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit);
			}
		}

		#endregion
	}
}