-
Notifications
You must be signed in to change notification settings - Fork 584
/
Copy pathErrorHandler.cs
191 lines (166 loc) · 7.21 KB
/
ErrorHandler.cs
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
188
189
190
191
#if NETSTANDARD2_0
using System.Text.Json;
using System.Text.Json.Nodes;
#else
using Newtonsoft.Json.Linq;
#endif
using SendGrid.Helpers.Errors.Model;
using System.Net.Http;
using System.Threading.Tasks;
using System;
using System.Linq;
namespace SendGrid.Helpers.Errors
{
/// <summary>
/// Error handler for requests.
/// </summary>
public class ErrorHandler
{
/// <summary>
/// Throw the exception based on HttpResponseMessage
/// </summary>
/// <param name="message">Response Message from API</param>
/// <returns>Return the exception. Obs: Exceptions from an Async Void Method Can’t Be Caught with Catch </returns>
public static async Task ThrowException(HttpResponseMessage message)
{
var errorMessage = await ErrorHandler.GetErrorMessage(message).ConfigureAwait(false);
var errorStatusCode = (int)message.StatusCode;
switch (errorStatusCode)
{
// 400 - BAD REQUEST
case 400:
throw new BadRequestException(errorMessage);
// 401 - UNAUTHORIZED
case 401:
throw new UnauthorizedException(errorMessage);
// 403 - FORBIDDEN
case 403:
throw new ForbiddenException(errorMessage);
// 404 - NOT FOUND
case 404:
throw new NotFoundException(errorMessage);
// 405 - METHOD NOT ALLOWED
case 405:
throw new MethodNotAllowedException(errorMessage);
// 413 - PAYLOAD TOO LARGE
case 413:
throw new PayloadTooLargeException(errorMessage);
// 415 - UNSUPPORTED MEDIA TYPE
case 415:
throw new UnsupportedMediaTypeException(errorMessage);
// 429 - TOO MANY REQUESTS
case 429:
throw new TooManyRequestsException(errorMessage);
// 500 - SERVER UNAVAILABLE
case 500:
throw new ServerUnavailableException(errorMessage);
// 503 - SERVICE NOT AVAILABLE
case 503:
throw new ServiceNotAvailableException(errorMessage);
}
// 4xx - Error with the request
if (errorStatusCode >= 400 && errorStatusCode < 500)
{
throw new RequestErrorException(errorMessage);
}
// 5xx - Error made by SendGrid
if (errorStatusCode >= 500)
{
throw new SendGridInternalException(errorMessage);
}
throw new BadRequestException(errorMessage);
}
/// <summary>
/// Get error based on Response from SendGrid API
/// Method taken from the StrongGrid project (https://github.com/Jericho/StrongGrid) with some minor changes. Thanks Jericho (https://github.com/Jericho)
/// </summary>
/// <param name="message">Response Message from API</param>
/// <returns>Return string with the error Status Code and the Message</returns>
private static async Task<string> GetErrorMessage(HttpResponseMessage message)
{
var errorStatusCode = (int)message.StatusCode;
var errorReasonPhrase = message.ReasonPhrase;
string errorValue = null;
string fieldValue = null;
string helpValue = null;
if (message.Content != null)
{
var responseContent = await message.Content.ReadAsStringAsync().ConfigureAwait(false);
if (!string.IsNullOrEmpty(responseContent))
{
try
{
// Check for the presence of property called 'errors'
#if NETSTANDARD2_0
var jObject = JsonNode.Parse(responseContent);
var errorsArray = (JsonArray)jObject["errors"];
if (errorsArray != null && errorsArray.Count > 0) {
// Get the first error message
errorValue = (string)errorsArray[0]["message"];
// Check for the presence of property called 'field'
if (errorsArray[0]["field"] != null) {
fieldValue = (string)errorsArray[0]["field"];
}
// Check for the presence of property called 'help'
if (errorsArray[0]["help"] != null) {
helpValue = (string)errorsArray[0]["help"];
}
}
else {
// Check for the presence of property called 'error'
var errorProperty = jObject["error"];
if (errorProperty != null) {
errorValue = (string)errorProperty;
}
}
#else
var jObject = JObject.Parse(responseContent);
var errorsArray = (JArray)jObject["errors"];
if (errorsArray != null && errorsArray.Count > 0)
{
// Get the first error message
errorValue = errorsArray[0]["message"].Value<string>();
// Check for the presence of property called 'field'
if (errorsArray[0]["field"] != null)
{
fieldValue = errorsArray[0]["field"].Value<string>();
}
// Check for the presence of property called 'help'
if (errorsArray[0]["help"] != null)
{
helpValue = errorsArray[0]["help"].Value<string>();
}
}
else
{
// Check for the presence of property called 'error'
var errorProperty = jObject["error"];
if (errorProperty != null)
{
errorValue = errorProperty.Value<string>();
}
}
#endif
}
catch
{
// Intentionally ignore parsing errors to return default error message
}
}
}
SendGridErrorResponse errorResponse = new SendGridErrorResponse
{
ErrorHttpStatusCode = errorStatusCode,
ErrorReasonPhrase = errorReasonPhrase,
SendGridErrorMessage = errorValue,
FieldWithError = fieldValue,
HelpLink = helpValue
};
#if NETSTANDARD2_0
return JsonSerializer.Serialize(errorResponse);
#else
return Newtonsoft.Json.JsonConvert.SerializeObject(errorResponse);
#endif
}
}
}