-
Notifications
You must be signed in to change notification settings - Fork 5k
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
Implement graceful error handling for trend charts #43090
Implement graceful error handling for trend charts #43090
Conversation
Codenotify: Notifying subscribers in CODENOTIFY files for diff 5e29f43...facb385.
|
|
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.
There was also a bit related to the inability to switch to other viz types if such error has happened. I think we should also address that even though it is not related to Trend viz. It is likely related to the logic in the Visualization.tsx component which has error
local state
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 is an old, dead conditional. There can no longer be a null or undefined trend returned. Either computeTrend
returns the actual trend, or throws an error.
const latestRowIndex = _.findLastIndex(rows, row => { | ||
const date = row[dimensionColIndex]; | ||
const value = row[metricColIndex]; | ||
|
||
return !isEmpty(value) && !isEmpty(date); | ||
}); | ||
if (latestRowIndex === -1) { | ||
throw Error("No rows contain a valid value."); | ||
} |
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 is the fix for the latest data point being null. If it is, we skip it and find the most recent non-null data point.
const date = rows[latestRowIndex][dimensionColIndex]; | ||
const value = rows[latestRowIndex][metricColIndex]; | ||
if (isEmpty(value) || isEmpty(date)) { |
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 conditional is no longer needed because of the fix above
const previousRowIndex = _.findLastIndex(rows, (row, i) => { | ||
if (i >= nextValueRowIndex) { | ||
return false; | ||
} | ||
|
||
const date = row[dimensionColIndex]; | ||
const value = row[metricColIndex]; | ||
|
||
return !isEmpty(value) && !isEmpty(date); | ||
}); | ||
|
||
// if no row exists with non-null date and non-null value | ||
if (isEmpty(previousRow)) { | ||
if (previousRowIndex === -1) { | ||
return null; | ||
} | ||
|
||
const prevDate = previousRow[dimensionColIndex]; | ||
const prevValue = previousRow[metricColIndex]; | ||
const prevDate = rows[previousRowIndex][dimensionColIndex]; | ||
const prevValue = rows[previousRowIndex][metricColIndex]; |
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.
Refactored this to have the same structure as getCurrentMetricData
does.
@@ -467,7 +471,7 @@ class Visualization extends PureComponent { | |||
(replacementContent && (dashcard.size_y !== 1 || isMobile) && !isAction); | |||
|
|||
return ( | |||
<ErrorBoundary> | |||
<ErrorBoundary onError={this.onRenderError}> |
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.
The reason users could not switch between visualizations or to the table view was because this ErrorBoundary
was catching the errors, but no function was provided to pass off that error information to the Visualization
component. Because it was not passed off, ErrorBoundary
held onto its local state of hasError
and therefore would not render its children.
if (error?.message) { | ||
return this.setState({ error: error.message }); | ||
} | ||
|
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.
The ErrorView
component within Visualization.jsx
expects the error to be a string. So we need to check if the error is a regular error object and only pass the string message.
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.
A generic error component was added to this on top of the regular error component, because they are serving different needs.
The regular error component contains errors that we are expecting to be thrown in certain conditions, and because of that, we have a particular error message we are wanting to display.
The generic error component is for errors that we are not expecting to be thrown and therefore have no specific message to display. We should still allow the user the option to get diagnostic info in order to help them out in the event that unintended errors are thrown.
@JesseSDevaney Did you forget to add a milestone to the issue for this PR? When and where should I add a milestone? |
* fix trend charts erroring on latest value being null * refactor previousRowIndex calculation * handle errors gracefully * refactor error messages * update computeTrend unit tests * add error handling integration test * add E2E test to check that errors are gracefully handled * add integration test to enforce the fix * fix static viz * display more meaningful error on static-viz trend charts * move error handling out of trend chart and fix error handling in Visualization.tsx * update compute.unit.spec.js * update SmartScalar.unit.spec.js * use separate error handler for ErrorBoundary errors in Visualization.jsx * update E2E test * update error handling * update compute.unit.spec.js * fix react state change error in render function * show generic error message for ErrorBoundary caught errors * revert ErrorBoundary changes * remove generic error border for visualizations
@metabase-bot backport release-x.49.x |
@JesseSDevaney something went wrong while creating a backport [Logs] |
* fix trend charts erroring on latest value being null * refactor previousRowIndex calculation * handle errors gracefully * refactor error messages * update computeTrend unit tests * add error handling integration test * add E2E test to check that errors are gracefully handled * add integration test to enforce the fix * fix static viz * display more meaningful error on static-viz trend charts * move error handling out of trend chart and fix error handling in Visualization.tsx * update compute.unit.spec.js * update SmartScalar.unit.spec.js * use separate error handler for ErrorBoundary errors in Visualization.jsx * update E2E test * update error handling * update compute.unit.spec.js * fix react state change error in render function * show generic error message for ErrorBoundary caught errors * revert ErrorBoundary changes * remove generic error border for visualizations Co-authored-by: Jesse Devaney <22608765+JesseSDevaney@users.noreply.github.com>
* fix trend charts erroring on latest value being null * refactor previousRowIndex calculation * handle errors gracefully * refactor error messages * update computeTrend unit tests * add error handling integration test * add E2E test to check that errors are gracefully handled * add integration test to enforce the fix * fix static viz * display more meaningful error on static-viz trend charts * move error handling out of trend chart and fix error handling in Visualization.tsx * update compute.unit.spec.js * update SmartScalar.unit.spec.js * use separate error handler for ErrorBoundary errors in Visualization.jsx * update E2E test * update error handling * update compute.unit.spec.js * fix react state change error in render function * show generic error message for ErrorBoundary caught errors * revert ErrorBoundary changes * remove generic error border for visualizations
* fix trend charts erroring on latest value being null * refactor previousRowIndex calculation * handle errors gracefully * refactor error messages * update computeTrend unit tests * add error handling integration test * add E2E test to check that errors are gracefully handled * add integration test to enforce the fix * fix static viz * display more meaningful error on static-viz trend charts * move error handling out of trend chart and fix error handling in Visualization.tsx * update compute.unit.spec.js * update SmartScalar.unit.spec.js * use separate error handler for ErrorBoundary errors in Visualization.jsx * update E2E test * update error handling * update compute.unit.spec.js * fix react state change error in render function * show generic error message for ErrorBoundary caught errors * revert ErrorBoundary changes * remove generic error border for visualizations Co-authored-by: Jesse Devaney <22608765+JesseSDevaney@users.noreply.github.com>
* fix trend charts erroring on latest value being null * refactor previousRowIndex calculation * handle errors gracefully * refactor error messages * update computeTrend unit tests * add error handling integration test * add E2E test to check that errors are gracefully handled * add integration test to enforce the fix * fix static viz * display more meaningful error on static-viz trend charts * move error handling out of trend chart and fix error handling in Visualization.tsx * update compute.unit.spec.js * update SmartScalar.unit.spec.js * use separate error handler for ErrorBoundary errors in Visualization.jsx * update E2E test * update error handling * update compute.unit.spec.js * fix react state change error in render function * show generic error message for ErrorBoundary caught errors * revert ErrorBoundary changes * remove generic error border for visualizations
Before
2024-05-23.14-56-03.mp4
After
2024-05-23.14-51-01.mp4
Desired Behavior/Acceptance Criteria
computeTrend
now finds the latest non-null data point and compares it with a the first non-null previous data pointcomputeTrend
throws an error, displays a warning icon and error message detailing the error.compute.unit.spec.js
,smartscalar.unit.spec.js
,smartscalar-trend.cy.spec.js
)