-
Notifications
You must be signed in to change notification settings - Fork 364
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
test: Improve Cypress error messages when Linode API errors occur #9777
test: Improve Cypress error messages when Linode API errors occur #9777
Conversation
// When a Linode APIv4 schema validation error occurs, an array of `APIError` | ||
// objects is thrown rather than a typical `Error` type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is intended, but I think this is the source of the behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah our error handling/normalization between Cloud Manager and api-v4 is a bit wacky
Are you saying that api-v4 throws Axios errors normally, but APIError[]
if it is a schema validation error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bnussman-akamai Yeah, that's my understanding -- an actual error from the API (like a 400 response, etc.) is an AxiosError<{ errors: APIError[] }>
whereas schema validation errors are just APIError[]
(in the schema validation Before screenshot in the PR description, Cypress even calls out that it's not an Error
that was thrown, but an array).
I don't really think it's a big deal, and even if this is a mistake I'm guessing we're in too deep now, just a little thing that caught me by surprise while working on this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I've noticed the same and agree we're in too deep 😅
On a semi related note, @jcallahan-akamai and I were just recently talking about how we can't see status codes because of our APIError[]
pattern. 😣
…occurs in Cypress test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// When a Linode APIv4 schema validation error occurs, an array of `APIError` | ||
// objects is thrown rather than a typical `Error` type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah our error handling/normalization between Cloud Manager and api-v4 is a bit wacky
Are you saying that api-v4 throws Axios errors normally, but APIError[]
if it is a schema validation error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Joe -- error messages were definitely a lot more helpful!
✅ confirmed error message for a weak root_password
✅ confirmed error message for a null root_password
errors: APIError[]; | ||
}; | ||
|
||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very well documented, makes it easy to follow, thank you!
* | ||
* @returns `true` if `e` is a Linode API v4 request error. | ||
*/ | ||
const isLinodeApiError = (e: any): e is AxiosError<LinodeApiV4Error> => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of curiosity, do you know why we use LinodeApiV4Error
instead of just using APIError[]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LinodeApiV4Error
is defined towards the top of this file, and it's just an alias for any object with an errors
property containing an array of APIError
s.
APIError[]
alone isn't applicable here because the error type we're checking for is an Axios error object which contains an HTTP response containing the errors. AxiosError<APIError[]>
also isn't applicable since the response body isn't just an array of APIError
objects, it's an object itself which contains an errors
property.
This could have been expressed as AxiosError<{ errors: APIError[] }>
, but I opted to define a type for this within the module because I expected to have to refer to that type a lot (in the end I really didn't).
// and request URL when applicable. | ||
const summary = !!e.response?.status | ||
? `Linode APIv4 request failed with status code ${e.response.status}` | ||
: `Linode APIv4 request failed`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it would be helpful here to add Linode APIv4 request failed **without status code**
for the false condition just so the user knows there wasn't one so they dont spend time looking for it?
const errorDetails = e.response!.data.errors.map((error: APIError) => { | ||
return error.field | ||
? `- ${error.reason} (field '${error.field}')` | ||
: `- ${error.reason}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
Its up to you though, I dont know if the status code and the error field are important, if not, feel free to disregard my comments.
const requestInfo = | ||
!!e.request?.responseURL && !!e.config.method | ||
? `\nRequest: ${e.config.method.toUpperCase()} ${e.request.responseURL}` | ||
: ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here
if (isValidationError(e)) { | ||
// Validation errors do not contain any additional context (request URL, payload, etc.). | ||
// Show the validation error messages instead. | ||
const multipleErrors = e.length > 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way to do this:
const errorPlurality = e.length > 1 ? 'errors' : 'error';
const summary = `Request failed with Linode schema validation ${errorPlurality}`;
: 'Request failed with Linode schema validation error'; | ||
|
||
// Format, accounting for 0, 1, or more errors. | ||
const validationErrorMessage = multipleErrors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since both conditions are pretty similar, another way to do it is:
const prefix = multipleErrors ? '- ' : '';
// Format, accounting for 0, 1, or more errors.
const validationErrorMessage = e
.map((error) =>
error.field
? `${prefix}${error.reason} (field '${error.field}')`
: `${prefix}${error.reason}`
)
.join('\n');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or tbh adding a hyphen before any error, even if its just one single error might still help readability. If this is the case, you wouldn't need the conditional.
Up to you though!
…node#9777) * Improve error messages when Linode API errors occur * Added changeset: Improve error message display when Linode API error occurs in Cypress test
Description 📝
This improves error handling when a Linode API error or validation error occurs during a Cypress test by adding additional information to the command log. This is intended to help troubleshoot test failures.
(Meta: Not sure if this is better suited as
test
orrefactor
type, happy to change this torefactor
if we think that's more applicable)Changes 🔄
cy.defer
Preview 📷
How to test 🧪
yarn cy:debug
:linodeRequest
incypress/support/util/linode-utils.ts
(line 10) to contain a short/weakroot_pass
propertyyarn cy:debug
and selectrescue-linode.spec.ts
in the UIAs an Author I have considered 🤔
Check all that apply