Include more details from SDK/API errors in the diagnostics#3379
Conversation
| alerts The alerts API can be used to perform CRUD operations on alerts. | ||
| alerts-legacy The alerts API can be used to perform CRUD operations on alerts. | ||
| alerts-v2 New version of SQL Alerts. | ||
| dashboards In general, there is little need to modify dashboards using the API. |
There was a problem hiding this comment.
Why are these commands removed?
There was a problem hiding this comment.
I did not regenerate SDK-based code, just removed things that did not compile. These will be cleaned up once we upgrade SDK.
There was a problem hiding this comment.
You can rebase to the latest main on CLI, which has SDK 0.79.0 already, so everything should compile there
There was a problem hiding this comment.
nice, thanks! done - these are gone now.
| return e.Error() + extra | ||
| } | ||
|
|
||
| func FormatAPIErrorDetails(e error) string { |
There was a problem hiding this comment.
Would be good to have a unit test for this to check the output when there is or no ResponseWrapper/Request/etc.
b52cf0a to
c2fb868
Compare
| if len(httpStatus) == 0 { | ||
| httpStatus = strconv.Itoa(apiErr.StatusCode) | ||
| } | ||
| return fmt.Sprintf("Endpoint: %s\nHTTP Status: %s\nAPI error_code: %s\nAPI message: %s", endpoint, httpStatus, apiErr.ErrorCode, apiErr.Message) |
There was a problem hiding this comment.
Is the API message always present or can it be empty?
There was a problem hiding this comment.
error_code -> error code?
They are not guaranteed to be set. I recall that the SDK does some work to populate them with HTTP error codes if there is no actual response, but double check...
There was a problem hiding this comment.
Yes, SDK tries very hard to populate those (e.g. it parses text and html) and falls back to setting them to UNKNOWN / full body.
So, if backend returns html or text, "API error_code" and "API message" labels are not strictly correct or rather they are represent SDK's view of error_code and message.
However, 99% of cases would get JSON error so "API error_code/message" does refer to error_code/message in the response. This is something that is mentioned in the docs, unlike "error code" which is vague.
BTW, this message is just a reasonably simple starting point. I think this message can be further improved in follow up PRs:
- We can distinguish JSON vs html/text errors (could be useful for debugging).
- We can mention useful headers (trace id?).
- We can include full request/response if user asked for more verbosity.
9 failing tests:
|
pietern
left a comment
There was a problem hiding this comment.
The check failure highlights that the API error can no longer be marshaled.
Exporting the whole response wrapper in the error feels very broad. To make this more focused and fix the check, you could consider adding 2 accessor functions on the API error to retrieve the corresponding request and response and keep the field to fetch them from unexported. That keeps the marshaled copy of the error identical and fix the check, but enables callers to get more information about errors.
| } | ||
| e = inner | ||
| } | ||
| return nil |
There was a problem hiding this comment.
This looks identical to errors.As. Can you use that instead?
| func FormatAPIErrorSummary(e error) string { | ||
| extra := "" | ||
| apiErr := findApiErr(e) | ||
| if apiErr != nil { |
There was a problem hiding this comment.
I recommend inverting this: return early if it isn't an API error. Function below does the same.
| if len(httpStatus) == 0 { | ||
| httpStatus = strconv.Itoa(apiErr.StatusCode) | ||
| } | ||
| return fmt.Sprintf("Endpoint: %s\nHTTP Status: %s\nAPI error_code: %s\nAPI message: %s", endpoint, httpStatus, apiErr.ErrorCode, apiErr.Message) |
There was a problem hiding this comment.
error_code -> error code?
They are not guaranteed to be set. I recall that the SDK does some work to populate them with HTTP error codes if there is no actual response, but double check...
c2fb868 to
fe79d41
Compare
fe79d41 to
3e19d66
Compare
5123233 to
cf5d91e
Compare
cf5d91e to
a798ebb
Compare
a798ebb to
7decdae
Compare
7decdae to
7b9c3f6
Compare
## Release v0.265.0 ### CLI * Fix "cache: token not found" for auth token command ([#3447](#3447)) ### Dependency updates * Upgrade TF provider to 1.87.0 ([#3430](#3430)) * Upgrade Go SDK to 0.81.0 ([#3449](#3449)) ### Bundles * Add support for Lakebase database instances in DABs ([#3283](#3283)) * Add support for Lakebase database catalogs in DABs ([#3436](#3436)) * Improve error message for SDK/API errors ([#3379](#3379)) * Separate generated classes between jobs and pipelines in Python support ([#3428](#3428))
…iagnostics (#3379) ## Changes - Any API error passed to diag.FromErr or logdiag.LogError will automatically be formatted to include HTTP status/message, HTTP method + full url, API code and message. - Custom error from direct deployment is removed, it's no longer needed. ## Why SDK errors by default only contain "message" from payload which sometimes looks like this "Request 123 failed". DABs/CLI do not add a lot of context to errors, so that message is all you see. This makes debugging very hard. I've been fixing this in direct deployment by - adding context to errors everywhere - tagging errors with endpoint This PR makes tagging unnecessary and adds better error handling to all of CLI - as long as you use logdiag.LogError, it'll add those critical details, see create-error test for example of the output. Requires databricks/databricks-sdk-go#1261 ## Tests Existing tests.
## Release v0.265.0 ### CLI * Fix "cache: token not found" for auth token command ([#3447](#3447)) ### Dependency updates * Upgrade TF provider to 1.87.0 ([#3430](#3430)) * Upgrade Go SDK to 0.81.0 ([#3449](#3449)) ### Bundles * Add support for Lakebase database instances in DABs ([#3283](#3283)) * Add support for Lakebase database catalogs in DABs ([#3436](#3436)) * Improve error message for SDK/API errors ([#3379](#3379)) * Separate generated classes between jobs and pipelines in Python support ([#3428](#3428))
Changes
Why
SDK errors by default only contain "message" from payload which sometimes looks like this "Request 123 failed".
DABs/CLI do not add a lot of context to errors, so that message is all you see.
This makes debugging very hard. I've been fixing this in direct deployment by
This PR makes tagging unnecessary and adds better error handling to all of CLI - as long as you use logdiag.LogError, it'll add those critical details, see create-error test for example of the output.
Requires databricks/databricks-sdk-go#1261
Tests
Existing tests.