Skip to content

Commit a86cf10

Browse files
authored
fix: got error response when create token (#152)
The empty redirect_url shown in request will cause error when user authorization url without redirect_url(it's valid case). Also fix parse create token error response to empty error object.
1 parent 038f987 commit a86cf10

File tree

5 files changed

+59
-16
lines changed

5 files changed

+59
-16
lines changed

authentication.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type AuthenticationClient struct {
2020
//
2121
// See https://developers.notion.com/reference/create-a-token
2222
func (cc *AuthenticationClient) CreateToken(ctx context.Context, request *TokenCreateRequest) (*TokenCreateResponse, error) {
23-
res, err := cc.apiClient.requestImpl(ctx, http.MethodPost, "oauth/token", nil, request, true)
23+
res, err := cc.apiClient.requestImpl(ctx, http.MethodPost, "oauth/token", nil, request, true, decodeTokenCreateError)
2424
if err != nil {
2525
return nil, err
2626
}
@@ -40,6 +40,15 @@ func (cc *AuthenticationClient) CreateToken(ctx context.Context, request *TokenC
4040
return &response, nil
4141
}
4242

43+
func decodeTokenCreateError(data []byte) error {
44+
var apiErr TokenCreateError
45+
err := json.Unmarshal(data, &apiErr)
46+
if err != nil {
47+
return err
48+
}
49+
return &apiErr
50+
}
51+
4352
// TokenCreateRequest represents the request body for AuthenticationClient.CreateToken.
4453
type TokenCreateRequest struct {
4554
// A unique random code that Notion generates to authenticate with your service,
@@ -51,7 +60,7 @@ type TokenCreateRequest struct {
5160
// the integration's Authorization settings. Do not include this field if a
5261
// "redirect_uri" query param was not included in the Authorization URL
5362
// provided to users. In most cases, this field is required.
54-
RedirectUri string `json:"redirect_uri"`
63+
RedirectUri string `json:"redirect_uri,omitempty"`
5564
// Required if and only when building Link Preview integrations (otherwise
5665
// ignored). An object with key and name properties. key should be a unique
5766
// identifier for the account. Notion uses the key to determine whether or not

authentication_test.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ func TestAuthenticationClient(t *testing.T) {
1717
statusCode int
1818
request *notionapi.TokenCreateRequest
1919
want *notionapi.TokenCreateResponse
20-
wantErr bool
21-
err error
20+
wantErr error
2221
}{
2322
{
2423
name: "Creates token",
@@ -37,20 +36,32 @@ func TestAuthenticationClient(t *testing.T) {
3736
WorkspaceId: "workspaceid_1",
3837
WorkspaceName: "workspace_1",
3938
},
40-
wantErr: false,
41-
err: nil,
39+
wantErr: nil,
40+
},
41+
{
42+
name: "Creates token",
43+
filePath: "testdata/create_token_error.json",
44+
statusCode: http.StatusBadRequest,
45+
request: &notionapi.TokenCreateRequest{
46+
Code: "code1",
47+
GrantType: "authorization_code",
48+
RedirectUri: "www.example.com",
49+
},
50+
wantErr: &notionapi.TokenCreateError{
51+
Code: "invalid_grant",
52+
Message: "Invalid code.",
53+
},
4254
},
4355
}
4456

4557
for _, tt := range tests {
4658
t.Run(tt.name, func(t *testing.T) {
4759
c := newMockedClient(t, tt.filePath, tt.statusCode)
4860
client := notionapi.NewClient("some_token", notionapi.WithHTTPClient(c))
49-
got, err := client.Authentication.CreateToken(context.Background(), tt.request)
61+
got, gotErr := client.Authentication.CreateToken(context.Background(), tt.request)
5062

51-
if (err != nil) != tt.wantErr {
52-
t.Errorf("Query() error = %v, wantErr %v", err, tt.wantErr)
53-
return
63+
if !reflect.DeepEqual(gotErr, tt.wantErr) {
64+
t.Errorf("Query() gotErr = %v, wantErr %v", gotErr, tt.wantErr)
5465
}
5566
if !reflect.DeepEqual(got, tt.want) {
5667
t.Errorf("Query() got = %v, want %v", got, tt.want)

client.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/json"
88
"fmt"
99
"io"
10+
"io/ioutil"
1011
"net/http"
1112
"net/url"
1213
"reflect"
@@ -23,6 +24,8 @@ const (
2324

2425
type Token string
2526

27+
type errJsonDecodeFunc func(data []byte) error
28+
2629
func (it Token) String() string {
2730
return string(it)
2831
}
@@ -112,10 +115,10 @@ func WithOAuthAppCredentials(id, secret string) ClientOption {
112115
}
113116

114117
func (c *Client) request(ctx context.Context, method string, urlStr string, queryParams map[string]string, requestBody interface{}) (*http.Response, error) {
115-
return c.requestImpl(ctx, method, urlStr, queryParams, requestBody, false)
118+
return c.requestImpl(ctx, method, urlStr, queryParams, requestBody, false, decodeClientError)
116119
}
117120

118-
func (c *Client) requestImpl(ctx context.Context, method string, urlStr string, queryParams map[string]string, requestBody interface{}, basicAuth bool) (*http.Response, error) {
121+
func (c *Client) requestImpl(ctx context.Context, method string, urlStr string, queryParams map[string]string, requestBody interface{}, basicAuth bool, errDecoder errJsonDecodeFunc) (*http.Response, error) {
119122
u, err := c.baseUrl.Parse(fmt.Sprintf("%s/%s", c.apiVersion, urlStr))
120123
if err != nil {
121124
return nil, err
@@ -187,18 +190,25 @@ func (c *Client) requestImpl(ctx context.Context, method string, urlStr string,
187190
}
188191

189192
if res.StatusCode != http.StatusOK {
190-
var apiErr Error
191-
err = json.NewDecoder(res.Body).Decode(&apiErr)
193+
data, err := ioutil.ReadAll(res.Body)
192194
if err != nil {
193195
return nil, err
194196
}
195-
196-
return nil, &apiErr
197+
return nil, errDecoder(data)
197198
}
198199

199200
return res, nil
200201
}
201202

203+
func decodeClientError(data []byte) error {
204+
var apiErr Error
205+
err := json.Unmarshal(data, &apiErr)
206+
if err != nil {
207+
return err
208+
}
209+
return &apiErr
210+
}
211+
202212
type Pagination struct {
203213
StartCursor Cursor
204214
PageSize int

error.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,12 @@ type RateLimitedError struct {
2020
func (e *RateLimitedError) Error() string {
2121
return e.Message
2222
}
23+
24+
type TokenCreateError struct {
25+
Code ErrorCode `json:"error"`
26+
Message string `json:"error_description"`
27+
}
28+
29+
func (e *TokenCreateError) Error() string {
30+
return e.Message
31+
}

testdata/create_token_error.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"error": "invalid_grant",
3+
"error_description": "Invalid code."
4+
}

0 commit comments

Comments
 (0)