g8rswimmer / go-twitter

This is a go library for twitter v2 API integration.
MIT License
315 stars 61 forks source link

`UserTweetTimeline` should return error when user id not found, but return nil #137

Closed p1ass closed 2 years ago

p1ass commented 2 years ago

Hi, I found the unexpected behavior of UserTweetTimeline.

Expect

When not found user id is passed to GET /2/users/{id}/tweets, API returns Not Found Error.

We can see this behavior using the official Twitter API playground:

https://oauth-playground.glitch.me/?id=usersIdTweets&params=%28%27query%21%28%29%7Ebody%21%27%27%7Epath%21%28%27id%21%272244994945%27%29%7Eid%21%27***9%27%299999%01*_

{
  "errors": [
    {
      "value": "99999999999999999",
      "detail": "Could not find user with id: [99999999999999999].",
      "title": "Not Found Error",
      "resource_type": "user",
      "parameter": "id",
      "resource_id": "99999999999999999",
      "type": "https://api.twitter.com/2/problems/resource-not-found"
    }
  ]
}

Actual

When using UserTweetTimeline method, error is null.

res, err := cli.UserTweetTimeline(context.Background, "99999999999999999", opts)
if err != nil {
    fmt.Println(err) // Not print
}

I think it is unexpected behavior and should return not found error.

What do you think of this?

g8rswimmer commented 2 years ago

@p1ass Thanks for the question with an example, I was able to see what you are referring to.

So from the example above, the response is as you describe. However, the reason that there was no error returned was that the HTTP response code was 200. This signifies that there was not an error and the request was properly handled.

Having said that, I understand your question. If you look at the API documentation there is an error object that can be returned by the request. This error object is in the response.

In this case, the status code is 200 but there are errors. This is detailed the twitter error documentation as a partial error.

In some cases you may see the errors detailed above in a response that returned a 200 status code. In those cases, the endpoint is designed to return the data that it can, while providing detailed errors about what it could not return.

Now the example that you gave looks like it should be some sort of 4xx error, but that is not what the API is returning.

p1ass commented 2 years ago

Thanks for replying to me.

I see, there are some partial errors with 200 responses. Partial errors are not considered as go error in g8rswimmer/go-twitter, so is it is recommend to get partial errors from TweetRaw struct?

g8rswimmer commented 2 years ago

@p1ass Yes the partial errors would be from the

        timeline, err := client.UserTweetTimeline(context.Background(), *userID, opts)
    switch {
        case err != nil:
               // handle http error
        case len(timeline.Raw.Errors) > 0:
             // handle partial errors
        default:
        }
g8rswimmer commented 2 years ago

Closing this issue. Add some documentation to the v2 readme to help with error handing.