Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 63ef92a

Browse files
Merge pull request #29 from notion-dotnet/feature/parse-error-response-and-make-it-available-in-exception
Parse error response and make it available in exception
2 parents b476e81 + 84c61cf commit 63ef92a

File tree

4 files changed

+109
-46
lines changed

4 files changed

+109
-46
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace Notion.Client
4+
{
5+
public enum NotionAPIErrorCode
6+
{
7+
[EnumMember(Value = "invalid_json")]
8+
InvalidJSON,
9+
10+
[EnumMember(Value = "invalid_request_url")]
11+
InvalidRequestURL,
12+
13+
[EnumMember(Value = "invalid_request")]
14+
InvalidRequest,
15+
16+
[EnumMember(Value = "validation_error")]
17+
ValidationError,
18+
19+
[EnumMember(Value = "missing_version")]
20+
MissingVersion,
21+
22+
[EnumMember(Value = "unauthorized")]
23+
Unauthorized,
24+
25+
[EnumMember(Value = "restricted_resource")]
26+
RestrictedResource,
27+
28+
[EnumMember(Value = "object_not_found")]
29+
ObjectNotFound,
30+
31+
[EnumMember(Value = "conflict_error")]
32+
ConflictError,
33+
34+
[EnumMember(Value = "rate_limited")]
35+
RateLimited,
36+
37+
[EnumMember(Value = "internal_server_error")]
38+
InternalServerError,
39+
40+
[EnumMember(Value = "service_unavailable")]
41+
ServiceUnavailable,
42+
}
43+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Notion.Client
2+
{
3+
class NotionApiErrorResponse
4+
{
5+
public NotionAPIErrorCode ErrorCode { get; set; }
6+
public string Message { get; set; }
7+
}
8+
}

‎Src/Notion.Client/NotionApiException.cs‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,32 @@
33

44
namespace Notion.Client
55
{
6-
class NotionApiException : Exception
6+
publicclass NotionApiException : Exception
77
{
8-
public NotionApiException(HttpStatusCode statusCode, string message) : this(statusCode, message, null)
8+
public NotionApiException(HttpStatusCode statusCode, NotionAPIErrorCode? notionAPIErrorCode, string message)
9+
: this(statusCode, notionAPIErrorCode, message, null)
910
{
1011
}
1112

12-
public NotionApiException(HttpStatusCode statusCode, string message, Exception innerException) : base(message, innerException)
13+
public NotionApiException(HttpStatusCode statusCode, string message)
14+
: this(statusCode, null, message, null)
1315
{
16+
}
17+
18+
public NotionApiException(
19+
HttpStatusCode statusCode,
20+
NotionAPIErrorCode? notionAPIErrorCode,
21+
string message,
22+
Exception innerException) : base(message, innerException)
23+
{
24+
NotionAPIErrorCode = notionAPIErrorCode;
25+
StatusCode = statusCode;
26+
1427
Data.Add("StatusCode", statusCode);
28+
Data.Add("NotionApiErrorCode", NotionAPIErrorCode);
1529
}
30+
31+
public NotionAPIErrorCode? NotionAPIErrorCode { get; }
32+
public HttpStatusCode StatusCode { get; }
1633
}
1734
}

‎Src/Notion.Client/RestClient/RestClient.cs‎

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -48,31 +48,42 @@ public async Task<T> GetAsync<T>(
4848
JsonSerializerSettings serializerSettings = null,
4949
CancellationToken cancellationToken = default)
5050
{
51-
EnsureHttpClient();
51+
varresponse=awaitSendAsync(uri,HttpMethod.Get,queryParams,headers,cancellationToken:cancellationToken);
5252

53-
string requestUri = queryParams == null ? uri : QueryHelpers.AddQueryString(uri, queryParams);
53+
return await response.ParseStreamAsync<T>(serializerSettings);
54+
}
5455

55-
var response = await SendAsync(requestUri, HttpMethod.Get, headers, cancellationToken: cancellationToken);
56+
private static async Task<Exception> BuildException(HttpResponseMessage response)
57+
{
58+
var errorBody = await response.Content.ReadAsStringAsync();
5659

57-
if (response.IsSuccessStatusCode)
60+
NotionApiErrorResponse errorResponse = null;
61+
if (!string.IsNullOrWhiteSpace(errorBody))
5862
{
59-
return await response.ParseStreamAsync<T>(serializerSettings);
63+
try
64+
{
65+
errorResponse = JsonConvert.DeserializeObject<NotionApiErrorResponse>(errorBody);
66+
}
67+
catch
68+
{
69+
}
6070
}
6171

62-
var message = !string.IsNullOrWhiteSpace(response.ReasonPhrase)
63-
? response.ReasonPhrase
64-
: await response.Content.ReadAsStringAsync();
65-
66-
throw new NotionApiException(response.StatusCode, message);
72+
return new NotionApiException(response.StatusCode, errorResponse?.ErrorCode, errorResponse.Message);
6773
}
6874

6975
private async Task<HttpResponseMessage> SendAsync(
7076
string requestUri,
7177
HttpMethod httpMethod,
78+
IDictionary<string, string> queryParams = null,
7279
IDictionary<string, string> headers = null,
7380
Action<HttpRequestMessage> attachContent = null,
7481
CancellationToken cancellationToken = default)
7582
{
83+
EnsureHttpClient();
84+
85+
requestUri = AddQueryString(requestUri, queryParams);
86+
7687
HttpRequestMessage httpRequest = new HttpRequestMessage(httpMethod, requestUri);
7788
httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _options.AuthToken);
7889
httpRequest.Headers.Add("Notion-Version", _options.NotionVersion);
@@ -84,7 +95,14 @@ private async Task<HttpResponseMessage> SendAsync(
8495

8596
attachContent?.Invoke(httpRequest);
8697

87-
return await _httpClient.SendAsync(httpRequest, cancellationToken);
98+
var response = await _httpClient.SendAsync(httpRequest, cancellationToken);
99+
100+
if (!response.IsSuccessStatusCode)
101+
{
102+
throw await BuildException(response);
103+
}
104+
105+
return response;
88106
}
89107

90108
private static void AddHeaders(HttpRequestMessage request, IDictionary<string, string> headers)
@@ -103,55 +121,27 @@ public async Task<T> PostAsync<T>(
103121
JsonSerializerSettings serializerSettings = null,
104122
CancellationToken cancellationToken = default)
105123
{
106-
EnsureHttpClient();
107-
108124
void AttachContent(HttpRequestMessage httpRequest)
109125
{
110126
httpRequest.Content = new StringContent(JsonConvert.SerializeObject(body, defaultSerializerSettings), Encoding.UTF8, "application/json");
111127
}
112128

113-
string requestUri = queryParams == null ? uri : QueryHelpers.AddQueryString(uri, queryParams);
114-
115-
var response = await SendAsync(requestUri, HttpMethod.Post, headers, AttachContent, cancellationToken: cancellationToken);
116-
117-
if (response.IsSuccessStatusCode)
118-
{
119-
return await response.ParseStreamAsync<T>(serializerSettings);
120-
}
121-
122-
var message = !string.IsNullOrWhiteSpace(response.ReasonPhrase)
123-
? response.ReasonPhrase
124-
: await response.Content.ReadAsStringAsync();
129+
var response = await SendAsync(uri, HttpMethod.Post, queryParams, headers, AttachContent, cancellationToken: cancellationToken);
125130

126-
thrownewNotionApiException(response.StatusCode,message);
131+
returnawaitresponse.ParseStreamAsync<T>(serializerSettings);
127132
}
128133

129134
public async Task<T> PatchAsync<T>(string uri, object body, IDictionary<string, string> queryParams = null, IDictionary<string, string> headers = null, JsonSerializerSettings serializerSettings = null, CancellationToken cancellationToken = default)
130135
{
131-
EnsureHttpClient();
132-
133136
void AttachContent(HttpRequestMessage httpRequest)
134137
{
135138
var serializedBody = JsonConvert.SerializeObject(body, defaultSerializerSettings);
136139
httpRequest.Content = new StringContent(serializedBody, Encoding.UTF8, "application/json");
137140
}
138141

139-
stringrequestUri = queryParams==null?uri:QueryHelpers.AddQueryString(uri, queryParams);
142+
varresponse = awaitSendAsync(uri,newHttpMethod("PATCH"), queryParams,headers,AttachContent,cancellationToken:cancellationToken);
140143

141-
var response = await SendAsync(requestUri, new HttpMethod("PATCH"), headers, AttachContent, cancellationToken: cancellationToken);
142-
143-
if (response.IsSuccessStatusCode)
144-
{
145-
return await response.ParseStreamAsync<T>(serializerSettings);
146-
}
147-
148-
var message = !string.IsNullOrWhiteSpace(response.ReasonPhrase)
149-
? response.ReasonPhrase
150-
: await response.Content.ReadAsStringAsync();
151-
152-
var errorMessage = await response.Content.ReadAsStringAsync();
153-
154-
throw new NotionApiException(response.StatusCode, message);
144+
return await response.ParseStreamAsync<T>(serializerSettings);
155145
}
156146

157147
private HttpClient EnsureHttpClient()
@@ -164,5 +154,10 @@ private HttpClient EnsureHttpClient()
164154

165155
return _httpClient;
166156
}
157+
158+
private static string AddQueryString(string uri, IDictionary<string, string> queryParams)
159+
{
160+
return queryParams == null ? uri : QueryHelpers.AddQueryString(uri, queryParams);
161+
}
167162
}
168163
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /