@@ -30,7 +30,7 @@ public class HttpProvider : IHttpProvider
30
30
/// <param name="authenticationProvider">The <see cref="IAuthenticationProvider"/> for authenticating request messages.</param>
31
31
/// <param name="serializer">A serializer for serializing and deserializing JSON objects.</param>
32
32
public HttpProvider ( IAuthenticationProvider authenticationProvider , ISerializer serializer = null )
33
- : this ( ( HttpMessageHandler ) null , true , authenticationProvider , serializer )
33
+ : this ( authenticationProvider , ( HttpMessageHandler ) null , true , serializer )
34
34
{
35
35
}
36
36
@@ -46,8 +46,8 @@ public HttpProvider(IAuthenticationProvider authenticationProvider, ISerializer
46
46
/// an <see cref="HttpClientHandler"/> to the constructor and enabling automatic redirects this could cause issues with authentication
47
47
/// over the redirect.
48
48
/// </remarks>
49
- public HttpProvider ( HttpClientHandler httpClientHandler , bool disposeHandler , IAuthenticationProvider authenticationProvider , ISerializer serializer = null )
50
- : this ( ( HttpMessageHandler ) httpClientHandler , disposeHandler , authenticationProvider , serializer )
49
+ public HttpProvider ( IAuthenticationProvider authenticationProvider , HttpClientHandler httpClientHandler , bool disposeHandler , ISerializer serializer = null )
50
+ : this ( authenticationProvider , ( HttpMessageHandler ) httpClientHandler , disposeHandler , serializer )
51
51
{
52
52
}
53
53
@@ -58,7 +58,7 @@ public HttpProvider(HttpClientHandler httpClientHandler, bool disposeHandler, IA
58
58
/// <param name="disposeHandler">Whether or not to dispose the client handler on Dispose().</param>
59
59
/// <param name="authenticationProvider">The <see cref="IAuthenticationProvider"/> for authenticating request messages.</param>
60
60
/// <param name="serializer">A serializer for serializing and deserializing JSON objects.</param>
61
- public HttpProvider ( HttpMessageHandler httpMessageHandler , bool disposeHandler , IAuthenticationProvider authenticationProvider , ISerializer serializer )
61
+ public HttpProvider ( IAuthenticationProvider authenticationProvider , HttpMessageHandler httpMessageHandler , bool disposeHandler , ISerializer serializer )
62
62
{
63
63
this . disposeHandler = disposeHandler ;
64
64
this . httpMessageHandler = httpMessageHandler ?? new HttpClientHandler { AllowAutoRedirect = false } ;
@@ -74,35 +74,6 @@ public HttpProvider(HttpMessageHandler httpMessageHandler, bool disposeHandler,
74
74
this . httpClient = GraphClientFactory . CreateClient ( this . httpMessageHandler , handlers ) ;
75
75
}
76
76
77
- /// <summary>
78
- /// Gets or sets the overall request timeout.
79
- /// </summary>
80
- public TimeSpan OverallTimeout
81
- {
82
- get
83
- {
84
- return this . httpClient . Timeout ;
85
- }
86
-
87
- set
88
- {
89
- try
90
- {
91
- this . httpClient . Timeout = value ;
92
- }
93
- catch ( InvalidOperationException exception )
94
- {
95
- throw new ServiceException (
96
- new Error
97
- {
98
- Code = ErrorConstants . Codes . NotAllowed ,
99
- Message = ErrorConstants . Messages . OverallTimeoutCannotBeSet ,
100
- } ,
101
- exception ) ;
102
- }
103
- }
104
- }
105
-
106
77
/// <summary>
107
78
/// Gets a serializer for serializing and deserializing JSON objects.
108
79
/// </summary>
@@ -140,6 +111,65 @@ public async Task<HttpResponseMessage> SendAsync(
140
111
HttpRequestMessage request ,
141
112
HttpCompletionOption completionOption ,
142
113
CancellationToken cancellationToken )
114
+ {
115
+ var response = await this . SendRequestAsync ( request , completionOption , cancellationToken ) . ConfigureAwait ( false ) ;
116
+
117
+ if ( ! response . IsSuccessStatusCode )
118
+ {
119
+ using ( response )
120
+ {
121
+ var errorResponse = await this . ConvertErrorResponseAsync ( response ) . ConfigureAwait ( false ) ;
122
+ Error error = null ;
123
+
124
+ if ( errorResponse == null || errorResponse . Error == null )
125
+ {
126
+ if ( response != null && response . StatusCode == HttpStatusCode . NotFound )
127
+ {
128
+ error = new Error { Code = ErrorConstants . Codes . ItemNotFound } ;
129
+ }
130
+ else
131
+ {
132
+ error = new Error
133
+ {
134
+ Code = ErrorConstants . Codes . GeneralException ,
135
+ Message = ErrorConstants . Messages . UnexpectedExceptionResponse ,
136
+ } ;
137
+ }
138
+ }
139
+ else
140
+ {
141
+ error = errorResponse . Error ;
142
+ }
143
+
144
+ if ( string . IsNullOrEmpty ( error . ThrowSite ) )
145
+ {
146
+ IEnumerable < string > throwsiteValues ;
147
+
148
+ if ( response . Headers . TryGetValues ( CoreConstants . Headers . ThrowSiteHeaderName , out throwsiteValues ) )
149
+ {
150
+ error . ThrowSite = throwsiteValues . FirstOrDefault ( ) ;
151
+ }
152
+ }
153
+
154
+ throw new ServiceException ( error )
155
+ {
156
+ // Pass through the response headers to the ServiceException.
157
+ ResponseHeaders = response . Headers ,
158
+
159
+ // System.Net.HttpStatusCode does not support RFC 6585, Additional HTTP Status Codes.
160
+ // Throttling status code 429 is in RFC 6586. The status code 429 will be passed through.
161
+ StatusCode = response . StatusCode
162
+ } ;
163
+ }
164
+ }
165
+
166
+ return response ;
167
+ }
168
+
169
+ internal async Task < HttpResponseMessage > SendRequestAsync (
170
+ HttpRequestMessage request ,
171
+ HttpCompletionOption completionOption ,
172
+ CancellationToken cancellationToken )
143
173
{
144
174
try
145
175
{
@@ -155,6 +185,10 @@ public async Task<HttpResponseMessage> SendAsync(
155
185
} ,
156
186
exception ) ;
157
187
}
188
+ catch ( ServiceException exception )
189
+ {
190
+ throw exception ;
191
+ }
158
192
catch ( Exception exception )
159
193
{
160
194
throw new ServiceException (
@@ -166,5 +200,28 @@ public async Task<HttpResponseMessage> SendAsync(
166
200
exception ) ;
167
201
}
168
202
}
203
+
204
+ /// <summary>
205
+ /// Converts the <see cref="HttpRequestException"/> into an <see cref="ErrorResponse"/> object;
206
+ /// </summary>
207
+ /// <param name="response">The <see cref="HttpResponseMessage"/> to convert.</param>
208
+ /// <returns>The <see cref="ErrorResponse"/> object.</returns>
209
+ private async Task < ErrorResponse > ConvertErrorResponseAsync ( HttpResponseMessage response )
210
+ {
211
+ try
212
+ {
213
+ using ( var responseStream = await response . Content . ReadAsStreamAsync ( ) . ConfigureAwait ( false ) )
214
+ {
215
+ return this . Serializer . DeserializeObject < ErrorResponse > ( responseStream ) ;
216
+ }
217
+ }
218
+ catch ( Exception )
219
+ {
220
+ // If there's an exception deserializing the error response return null and throw a generic
221
+ // ServiceException later.
222
+ return null ;
223
+ }
224
+ }
225
+
169
226
}
170
227
}
0 commit comments