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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
//-----------------------------------------------------------------------
// <copyright file="ProtocolException.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace DotNetOAuth.Messaging {
using System;
using System.Collections.Generic;
/// <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>
/// A cache for extra name/value pairs tacked on as data when this exception is sent as a message.
/// </summary>
private Dictionary<string, string> extraData = new Dictionary<string, string>();
/// <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="faultedMessage">The message that was the cause of the exception. May not be null.</param>
internal ProtocolException(string message, IProtocolMessage faultedMessage) : base(message) {
if (faultedMessage == null) {
throw new ArgumentNullException("faultedMessage");
}
this.FaultedMessage = faultedMessage;
}
/// <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;
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;
}
/// <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 {
if (this.inResponseTo == null) {
throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit);
}
return this.recipient;
}
}
#endregion
#region IProtocolMessage Properties
/// <summary>
/// Gets the version of the protocol this message is prepared to implement.
/// </summary>
Version IProtocolMessage.ProtocolVersion {
get {
if (this.inResponseTo == null) {
throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit);
}
return this.inResponseTo.ProtocolVersion;
}
}
/// <summary>
/// Gets the level of protection this exception requires when transmitted as a message.
/// </summary>
MessageProtection IProtocolMessage.RequiredProtection {
get { return MessageProtection.None; }
}
/// <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>
/// Gets the dictionary of additional name/value fields tacked on to this message.
/// </summary>
IDictionary<string, string> IProtocolMessage.ExtraData {
get { return this.extraData; }
}
#endregion
/// <summary>
/// Gets the message that caused the exception.
/// </summary>
internal IProtocolMessage FaultedMessage {
get;
private set;
}
#region IProtocolMessage Methods
/// <summary>
/// See <see cref="IProtocolMessage.EnsureValidMessage"/>.
/// </summary>
void IProtocolMessage.EnsureValidMessage() {
if (this.inResponseTo == null) {
throw new InvalidOperationException(MessagingStrings.ExceptionNotConstructedForTransit);
}
}
#endregion
}
}
|