-
Notifications
You must be signed in to change notification settings - Fork 240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
APIError unmarshaling broken in 1.4 #339
Comments
Oh, to be clear, this was using v1.4.1, though I don't think any differences between v1.4.0 and v1.4.1 are relevant. |
@dsymonds I would need a reproduction case so that I can figure it out. |
I reproduced it with the Using an input file like: {
"start": "2021-06-29T12:00:00Z",
"end": "2021-06-29T18:00:00Z",
"user": {...}
} or with any other date in the past, you can get an API response like: {"message":"Invalid Override","code":2001,"errors":"Override must end in the future, Override must end after its start"} and that doesn't unmarshal into the |
@dsymonds thank you for that. That https://developer.pagerduty.com/docs/rest-api-v2/errors/ @stmcallister could you ping someone inside of PagerDuty to see whether that's expected? API documentation shows |
Interestingly, when I create an override with a raw API call, using dates in the past as you did, my errors object is an array of strings.
|
I'm noticing that the output @stmcallister provided looks to be an array of objects, which may explain the failure. If so, I should be able to fix that. While looking into that, though, I'm actually surprised the code works at all since it seems to provide a different payload than what the documentation shows. The documentation says the payload needs to be an object with one key, In our code, it's a single object at the key Lines 261 to 265 in e23b94c
It seems like we might be making use of some undocumented API feature that allows us to specify a single object. We probably need to fix this too, to be aligned with the spec. |
This is to help with debugging issue #339. This branch is based off of #325, so that I could make use of the new response debugging functionality I added. I ran the following commands from within the `command` directory to get the below result: ```shell go build -o pd . ./pd schedule override create -authtoken "$(cat ../api.key)" PF4QFIN debug_override.json ``` The `api.key` file is just an API key from the PD console. `PF4QFIN` is a PagerDuty service in my development account. Here is the output: ``` time="2021-07-04T01:00:24-07:00" level=info msg="service id is:PF4QFIN" time="2021-07-04T01:00:24-07:00" level=info msg="Input file is:debug_override.json" req: req.Method: POST req.URL: https://api.pagerduty.com/schedules/PF4QFIN/overrides req.Header: http.Header{"Accept":[]string{"application/vnd.pagerduty+json;version=2"}, "Authorization":[]string{"Token token=u+XP5yPH7pzsQ3aJA5EQ"}, "Content-Type":[]string{"application/json"}, "User-Agent":[]string{"go-pagerduty/1.5.0"}} req.Body: {"override":{"start":"2021-06-29T12:00:00Z","end":"2021-06-29T18:00:00Z","user":{"id":"P6QKA9O"}}} err: HTTP response with status code 400, JSON error object decode failed: json: cannot unmarshal string into Go struct field APIError.error of type []string resp: resp.Status: 400 Bad Request resp.Header: http.Header{"Access-Control-Allow-Headers":[]string{"Authorization, Content-Type, AuthorizationOauth, X-EARLY-ACCESS"}, "Access-Control-Allow-Methods":[]string{"GET, POST, PUT, DELETE, OPTIONS"}, "Access-Control-Allow-Origin":[]string{"*"}, "Access-Control-Expose-Headers":[]string{""}, "Access-Control-Max-Age":[]string{"1728000"}, "Cache-Control":[]string{"no-cache"}, "Connection":[]string{"keep-alive"}, "Content-Length":[]string{"95"}, "Content-Type":[]string{"application/json"}, "Date":[]string{"Sun, 04 Jul 2021 08:00:24 GMT"}, "Server":[]string{"nginx"}, "X-Request-Id":[]string{"f6cda459-587c-49a6-ab98-17fc5bd60642"}} resp.Body: {"error":{"message":"Invalid Override","code":2001,"errors":"Invalid input for this override"}} ``` Note that `error.errors` is not an array, it's a single string. This seems to violate the API spec.
@stmcallister I was able to repro this, and created a dedicated branch with some extra debug code to show it: https://github.com/PagerDuty/go-pagerduty/tree/debugging_weird_errors This specific commit has the instructions for how to use that branch to show the API returning an incompatible response: b053fc7 In summary, cd command
go build -o pd .
./pd schedule override create -authtoken "$(cat ../api.key)" PF4QFIN debug_override.json |
@stmcallister I could also replicate it with: curl -v -X POST \
-H 'Accept: application/vnd.pagerduty+json;version=2' \
-H 'Authorization: Token token=u+GLqAhVYVnyjWVAhZYg' \
-H 'Content-Type: application/json' \
--data '{"override":{"start":"2021-06-29T12:00:00Z","end":"2021-06-29T18:00:00Z","user":{"id":"P6QKA9O"}}}' \
https://api.pagerduty.com/schedules/PF4QFIN/overrides
My expectation is that the JSON would instead look like this: {"error":{"message":"Invalid Override","code":2001,"errors":["Invalid input for this override"]}} Note: the API key shown here is no longer valid. |
I'll see whether there is a way to fix this within a v1.4.x patch release, but from what I remember from when I explored it last this is maybe a side effect of us using the API incorrectly. We send JSON in a format different than the API documentation specifies, and since I'll be fixing some of that in v1.5.0 I may try to do it within that version. |
I know nobody else but me (and maybe PD employees) can see this, but I've filed a support ticket with PagerDuty to try and get a sense of what the right path forward is here: https://tickets.pagerduty.com/hc/requests/341221 This feels like an obvious REST API bug to me, but I'm unsure if PagerDuty feels the same. I'll loop-back on this issue once I've some sort of resolution from that support ticket. |
The ticket is still open with PagerDuty Support. The last communication from them on Sept 5th was that they would be escalating it to engineering, and I'd hear back once they have an answer. I'll loop back around to see if they have an estimate of when that may be. |
I believe I'm hitting this bug with a this call:
The value of The value of
When I changed the code to dump the body, I see:
|
I just pinged PagerDuty again for our monthly check-in, as well as asked if there are any engineers I can bribe to look at it sooner. 😅 I'll look at this again before v1.5.0 to see if I can noodle on a temporary shim to handle this bad error format edge case, or see if there are other options. |
The PagerDuty REST API documentation[1] indicates that the `errors` field of an error response is an array of error strings. However, as shown in #339 the API sometimes violates that specification and instead returns the `errors` field as a string. There is a PagerDuty customer support ticket open[2] to to address this issue, but there is currently no ETA on the resolution. As such we are going to create this workaround to properly parse the invalid responses and return the proper error type to callers. Closes #339 [1] https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTYz-errors [2] https://tickets.pagerduty.com/hc/requests/341221
The PagerDuty REST API documentation[1] indicates that the `errors` field of an error response is an array of error strings. However, as shown in #339 the API sometimes violates that specification and instead returns the `errors` field as a string. There is a PagerDuty customer support ticket open[2] to to address this issue, but there is currently no ETA on the resolution. As such we are going to create this workaround to properly parse the invalid responses and return the proper error type to callers. Closes #339 [1] https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTYz-errors [2] https://tickets.pagerduty.com/hc/requests/341221
Alrighty. Since it doesn't seem like PagerDuty engineering may be able fix this for a bit of time, I raised #382 to address this bug on our side by trying to reparse the JSON if it seems to fail due to mismatched types. |
The bug this fixes was introduced as part of v1.4.0, so we need to backport it into the v1.4.x release line. Because the master branch has diverged towards v1.5.0, we need to manually backport this to the release-1.4.x branch. Original commit message (0933613): The PagerDuty REST API documentation[1] indicates that the errors field of an error response is an array of error strings. However, as shown in #339 the API sometimes violates that specification and instead returns the errors field as a string. There is a PagerDuty customer support ticket open[2] to to address this issue, but there is currently no ETA on the resolution. As such we are going to create this workaround to properly parse the invalid responses and return the proper error type to callers. Closes #339 [1] https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTYz-errors [2] https://tickets.pagerduty.com/hc/requests/341221
The bug this fixes was introduced as part of v1.4.0, so we need to backport it into the v1.4.x release line. Because the master branch has diverged towards v1.5.0, we need to manually backport this to the release-1.4.x branch. Original commit message (0933613): The PagerDuty REST API documentation[1] indicates that the errors field of an error response is an array of error strings. However, as shown in #339 the API sometimes violates that specification and instead returns the errors field as a string. There is a PagerDuty customer support ticket open[2] to to address this issue, but there is currently no ETA on the resolution. As such we are going to create this workaround to properly parse the invalid responses and return the proper error type to callers. Closes #339 Backports #382 [1] https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTYz-errors [2] https://tickets.pagerduty.com/hc/requests/341221
@dsymonds I just backported the fix or this into the |
When making some types of API calls, the error response fails to unmarshal into the JSON structures and so the error itself is lost to client code, who only gets a JSON error. In particular, I was creating an override in the past, and triggered this.
My apologies for not capturing the error itself (I worked around it, then lost my terminal history), but it should be easy to reproduce. Let me know if that's not the case and I'll try to go back into my local history.
The text was updated successfully, but these errors were encountered: