creachadair / twitter

A Go client for the Twitter v2 API (in development).
MIT License
31 stars 2 forks source link

Parse and report JSON error messages when requests fail #1

Closed creachadair closed 4 years ago

creachadair commented 4 years ago

On error, the v2 API reports a JSON text along with the status code. The exact format isn't clear, but it has the general shape:

{
  "errors": [ {"message": "you done broke it", "code": 45} ]
}

The response codes are defined here: https://developer.twitter.com/en/docs/response-codes. In the wild, though, the format varies quite a bit. Sometimes the top-level message has status and details as additional keys:

{
  "errors": [
    {
      "parameters": {
        "expansions": [
          "3"
        ]
      },
      "message": "The `expansions` query parameter value [3] is not one of [pinned_tweet_id]"
    }
  ],
  "title": "Invalid Request",
  "detail": "One or more parameters to your request was invalid.",
  "type": "https://api.twitter.com/2/problems/invalid-request"
}

Other times everything is inside the array:

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

The API docs don't appear to document the expected formats. Figure out some reasonable way to interpret these values, and attach them to error values.

creachadair commented 4 years ago

This seems to have some useful details: https://developer.twitter.com/en/support/twitter-api/error-troubleshooting

A couple of key points here:

creachadair commented 4 years ago

From the OpenAPI schema:

curl https://api.twitter.com/2/openapi.json|jq '.components.schemas.Error'
{
  "required": [
    "code",
    "message"
  ],
  "properties": {
    "code": {
      "type": "integer",
      "format": "int32"
    },
    "message": {
      "type": "string"
    }
  }
}

This matches what's mentioned in the response codes doc. The schema also incorporates the RFC 7807 HTTP Problem Details object. That looks closer to what I'm getting.

creachadair commented 4 years ago

Commit 3607a3d2 et seq. address part of this issue. The error wrapper now captures the error response and allows the caller to retrieve it, but I didn't add any data types for decoding the contents. The RFC 7807 schema looks more complicated than I really want to deal with right now.

creachadair commented 4 years ago

Commit 30ee1684 addresses most of this, to the point where I'm going to consider this issue resolved. There are still some corner cases I think we don't handle, but the basic plumbing works and I can fix other errors as they arise.