-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
KibanaErrorBoundary initial implementation #168754
KibanaErrorBoundary initial implementation #168754
Conversation
6798559
to
7ba611b
Compare
7237345
to
87d5809
Compare
f19fbcf
to
83bb621
Compare
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.
Overall looks very good 👍! Added few non-critical comments.
x-pack/plugins/reporting/public/management/mount_management_section.tsx
Outdated
Show resolved
Hide resolved
x-pack/plugins/reporting/public/management/mount_management_section.tsx
Outdated
Show resolved
Hide resolved
packages/shared-ux/error_boundary/src/services/error_boundary_services.tsx
Outdated
Show resolved
Hide resolved
* Kibana-specific Provider that maps dependencies to services. | ||
*/ | ||
export const ErrorBoundaryKibanaProvider: FC = ({ children }) => { | ||
const reloadWindow = () => window.location.reload(); |
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.
Maybe this could be part of the errorService
, so that we pass around only one object, like:
errorService.reload();
Then, at least for forceable future, we can simplify the value of our context to a single field—there is just one "service" object which manages all dependencies (in the future), and contains all the business logic for dealing with errors.
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.
Not sure about this, it feels like just a bit of indirection.
In the future, I also plan to add a ToastsService
to the mix of services. This will maintain the internal state about the toast objects that get sent to the EuiGlobalToastList
.
7a7f067
to
e8ebb2d
Compare
Pinging @elastic/appex-sharedux (Team:SharedUX) |
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 tested tags management (in Firefox), works good 👍
*/ | ||
export const KibanaErrorBoundaryProvider: FC = ({ children }) => { | ||
// control side-effects of rendering with useMemo | ||
const reloadWindow = useMemo(() => () => window.location.reload(), []); |
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 probably should be
const reloadWindow = useMemo(() => () => window.location.reload(), []); | |
const reloadWindow = useCallback(() => window.location.reload(), []); |
But I am not sure that there is any benefit to it, since value
below is always a new object and children will have to re-render. see https://legacy.reactjs.org/docs/context.html#caveats
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.
realoadWindow
is so tiny, it is probably more efficient to create a new function every re-render than to memoize it:
const reloadWindow = useMemo(() => () => window.location.reload(), []); | |
const reloadWindow = () => window.location.reload(); |
For the context provider value object to always have the same identity, so that other components don't re-render if this component re-renders, the context value could be a single object:
const value = useMemo(() => new KibanaErrorBoundaryServices(), []);
return <Context.Provider value={value}>{children}</Context.Provider>;
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 these suggestions!
Since KibanaErrorBoundaryServices
is just an interface, I'll go with:
const value: KibanaErrorBoundaryServices = useMemo(
() => ({
reloadWindow: () => window.location.reload(),
errorService: new KibanaErrorService(),
}),
[]
);
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.
LGTM 👍 Below are just a bunch of optional improvements.
packages/shared-ux/error_boundary/src/services/error_boundary_services.tsx
Outdated
Show resolved
Hide resolved
packages/shared-ux/error_boundary/src/ui/message_components.tsx
Outdated
Show resolved
Hide resolved
packages/shared-ux/error_boundary/src/ui/message_components.tsx
Outdated
Show resolved
Hide resolved
packages/shared-ux/error_boundary/src/ui/message_components.tsx
Outdated
Show resolved
Hide resolved
@elasticmachine merge upstream |
💚 Build Succeeded
Metrics [docs]Public APIs missing comments
Async chunks
Page load bundle
Unknown metric groupsAPI count
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: |
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.
ops changes lgtm
@tsullivan I'm running into a problem with this error boundary: when an error occurs during development, I want to see the stack trace and navigate to the file where the error was thrown. Afaict that is no longer possible, since the stack trace is not written to the console and the stack trace printed in the UI is not clickable (does not allow navigating to the file). It is not easy to decipher the stack trace because it refers to "chunks" and not files. For instance, see this stack traces that's printed by the error boundary:
WDYT about printing the stack trace to the console, thereby re-enabling the ability to interact with it? |
@sorenlouv My apologies for the oversight! It sounds like you expected this logging: #189925 |
Log the error that was caught to the console, so developers can interact with the stack trace messages. Addresses #168754 (comment)
Summary
This PR creates the
ErrorBoundary
component and its provider for services. It implements the wrapper around a few management apps owned by Appex-SharedUX.Screenshots
Updated 2023-10-18
Server upgrade scenario: In this case, the caught error is known to be recoverable via window refresh:
Unknown/Custom error: In this case, the error is something outside of known cases where the fix is to refresh:
Testing
Checklist