-
Notifications
You must be signed in to change notification settings - Fork 43
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
chore: improve error notifications in annotations and notebooks #6927
Conversation
just noticed you marked this back to "Draft". Ping me when it's ready for a review and I'll take a look
I noticed that annotations and notebooks could display the api error when requests fail - they are not consistent about it.
745ec79
to
d390f20
Compare
@@ -140,7 +140,7 @@ export const AnnotationForm: FC<Props> = (props: Props) => { | |||
} | |||
|
|||
try { | |||
dispatch(deleteAnnotations(editedAnnotation)) | |||
await dispatch(deleteAnnotations(editedAnnotation)) |
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.
@blegesse-w, @wdoconnell - perhaps you can help me here? I don't know react/redux so I'm just guessing.
What I am observing is that when the api call within deleteAnnotations
fails - it throws an Error if the http code is >= 300 - it is not caught at line 149 - so this delete annotation always appears to be successful in the ui even if the api call fails.
I guess that the issue is that the dispatch is async so this code advances to the notify success before the error arrives, but this isn't an async context so I added
const handleDelete = async (): Promise<void> => {
but that still doesn't catch the error thrown.
Any idea?
I have noticed that if editing an annotation or creating an annotation fails at the api, those errors are caught in their catch
blocks but I can't see what is different in those code paths and this code path.
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.
You can see here that the delete and put api calls are structured identically to my eye and these are where api errors are thrown
ui/src/annotations/api/index.ts
Lines 77 to 101 in f46e47d
export const updateAnnotation = async ( | |
newAnnotation: AnnotationEvent | |
): Promise<AnnotationEvent> => { | |
const params = {annotationID: newAnnotation.id, data: newAnnotation} | |
const res = await putAnnotation(params) | |
if (res.status >= 300) { | |
throw new Error(res.data?.message) | |
} | |
return res.data | |
} | |
export const deleteAnnotation = async ( | |
annotationToDelete: DeleteAnnotation | |
): Promise<number> => { | |
const params = {annotationID: annotationToDelete.id} | |
const res = await deleteAnnotationApi(params) | |
if (res.status >= 300) { | |
throw new Error(res.data?.message) | |
} | |
return res.status | |
} |
The put/edit errors are caught tho and the delete one isn't.
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.
This edit annotation seems to catch thrown api errors so i was trying to make the delete code look the same
ui/src/annotations/components/EditAnnotationOverlay.tsx
Lines 41 to 57 in f46e47d
const handleSubmit = async ( | |
editedAnnotation: EditAnnotation | |
): Promise<void> => { | |
try { | |
await dispatch(editAnnotation(editedAnnotation)) | |
event( | |
`${clickedAnnotation.eventPrefix}.annotations.edit_annotation.success` | |
) | |
dispatch(notify(editAnnotationSuccess())) | |
onClose() | |
} catch (err) { | |
event( | |
`${clickedAnnotation.eventPrefix}.annotations.edit_annotation.failure` | |
) | |
dispatch(notify(editAnnotationFailed(getErrorMessage(err)))) | |
} | |
} |
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.
Hey @philjb thanks for tagging me in. I can't say what the problem is for sure but from a quick glance at the code, it does look like the issue might be with how the deleteAnnotations API call is handling errors. From what I can see, even though you're using await in your try...catch block, the error isn't getting caught as expected. This could be happening if the deleteAnnotations function isn't throwing the error properly when the API call fails.
Here is what i suggest. Double-check that deleteAnnotations is an asynchronous action creator that throws an error when the API responds with a status code of 300 or higher. This way, the error will propagate correctly up to your try...catch block.
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.
Also it's probably worth checking that the redux thunk is not swallowing the error before it reaches your catch block.
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 for taking a look Beth! I think those are good suggestions, I just don't know how to do them. I don't know what a asynchronous action creator
is or how to check it. I did walk through the code with the browser debugger and it appears to throw the error - it's hard for me to see how it couldn't throw the error at these lines:
ui/src/annotations/api/index.ts
Lines 96 to 98 in f46e47d
if (res.status >= 300) { | |
throw new Error(res.data?.message) | |
} |
redux thunk is not swallowing the error
Presumably the error is getting caught somewhere since it isn't caught where I want, but I don't know how to check where it is getting caught.
I'm happy to learn to fish here but you'll be teaching me react/redux - for instance, i don't know what a redux thunk
is.
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.
@philjb No worries, Phil! I’ll take a closer look at this tomorrow with Bill, and we’ll figure out what's going on. I know the whole async/Redux world can be a bit tricky so I'll make sure to loop you in as I go
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 did some debugging on this locally and reached a similar solution to yours—adding await
before the dispatch(deleteAnnotations(editedAnnotation))
call. But, one key detail is that the handleDelete function itself needs to be marked as async
to make sure the await
statement works as intended.
Once you add the async
keyword to handleDelete
, everything should work perfectly. Nice job identifying the main fix!
Checkout the UI behavior after I forced an error in the deleteAnnotations
thunk to simulate a failed API request:
https://github.com/user-attachments/assets/fa7a2925-73e1-4b2f-9be0-187fb943b674
error propagation is working and the UI displays the correct message on failure.
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 think it was an issue with my local testing. I thought yarn build
would rebuild everything but it apparently doesn't so i'm cleaning the build/
dir now and then rebuilding. I was on the right track- sorry i didn't figure it out entirely myself. thank you for your help!! very validating.
Including the underlying error in error messages, this improves notebooks, dashboards, labels, and annotations. Many other error notifications all need improving e.g. in tasks and secrets.
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.
PR LGTM. But I do see a few unrelated failed monitor ci tests. You might need to push an empty commit so the tests can run on a clean pipeline.
Thanks Beth! These are the test failing that i see
|
@philjb UI feature branches are clearing our tests properly now. You should be able to rebase against the current master branch and force-push to successfully re-run. Thanks for your patience. |
master merged in! |
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.
Thank you for doing this!
* chore: improve error notifications in annotations and notebooks I noticed that annotations and notebooks could display the api error when requests fail - they are not consistent about it. * fix: improve failure error message notifications Including the underlying error in error messages, this improves notebooks, dashboards, labels, and annotations. Many other error notifications all need improving e.g. in tasks and secrets. * chore: run yarn prettier:fix * chore: whitespace to trigger ci
…ry-pick) (#6953) * chore: improve error notifications in annotations and notebooks (#6927) * chore: improve error notifications in annotations and notebooks I noticed that annotations and notebooks could display the api error when requests fail - they are not consistent about it. * fix: improve failure error message notifications Including the underlying error in error messages, this improves notebooks, dashboards, labels, and annotations. Many other error notifications all need improving e.g. in tasks and secrets. * chore: run yarn prettier:fix * chore: whitespace to trigger ci * chore: run prettier
I noticed that annotations, dashboards, labels, and notebooks sometimes display the api error when requests fail and sometimes don't- they are not consistent about it. I'd like to have it be consistent to be clear about errors.
I did not improve all error messages: variables, secrets, tasks, etc could also be improved but this is progress!
This needs to be ported to the OSS release branch.
Examples of the error notification popups:
Checklist
Authors and Reviewer(s), please verify the following: