Skip to content
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

Fixes #23709 - StatisticsCharts fails handling errors #5616

Merged
merged 1 commit into from Jun 18, 2018
Merged

Fixes #23709 - StatisticsCharts fails handling errors #5616

merged 1 commit into from Jun 18, 2018

Conversation

boaz0
Copy link
Member

@boaz0 boaz0 commented May 27, 2018

/cc @ohadlevy @amirfefer @sharvit

It seems like when an error occures during fetching the data the error object is not passed to ChartBox as a string.
In addition, the action payload is different when error occures, causing the error message to be in a new ChartBox.

Before

statistics_empty

console error

After

fine

@theforeman-bot
Copy link
Member

Issues: #23709

@coveralls
Copy link

Coverage Status

Coverage remained the same at 79.425% when pulling cc62291 on ripcurld:fixes_23709 into 59cdda3 on theforeman:develop.

2 similar comments
@coveralls
Copy link

Coverage Status

Coverage remained the same at 79.425% when pulling cc62291 on ripcurld:fixes_23709 into 59cdda3 on theforeman:develop.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 79.425% when pulling cc62291 on ripcurld:fixes_23709 into 59cdda3 on theforeman:develop.

Copy link
Member

@ohadlevy ohadlevy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, but 1. I have now idea how it stopped working (could be axios pr related? @amirfefer ?) and wondering if we can add a test for it?

@boaz0
Copy link
Member Author

boaz0 commented May 27, 2018

@ohadlevy Yes sure, I am working on this right now.
If I have time, I can git-blame and investigate this more.
Although, it seems to me like an honest mistake in the unit-tests.

@boaz0
Copy link
Member Author

boaz0 commented May 31, 2018

@ohadlevy you're right: a5a6b5d#diff-0be26feab8a96771c4d11efe9e3758c1L13.
jquery.ajax returns error as string while axios returns it as Error.
Also, here - it used to have id and error but now it has error and item which causes a different problem.

In regards to why tests pass - we don't have tests to ajaxRequestAction. So there was no way to make sure moving to axios would break something. Also, looking at the fixtures in reducers (such as in statistics) I find it odd that they were set to an empty object from the beginning especially that they were strings.

Anyway, this patch fixes all these regressions - adding more tests and fixing some (due to moving to axios) .

Thanks for the information Ohad.

pondrejk
pondrejk previously approved these changes Jun 4, 2018
@@ -11,5 +11,5 @@ export const ajaxRequestAction = ({
dispatch({ type: requestAction, payload: item });
return API.get(url)
.then(({ data }) => dispatch({ type: successAction, payload: { ...item, ...data } }))
.catch(error => dispatch({ type: failedAction, payload: { error, item } }));
.catch(error => dispatch({ type: failedAction, payload: { item, error: error.message } }));
Copy link
Member

@amirfefer amirfefer Jun 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it work with all the components that use ajaxRequestAction?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does. I did do manual testing if that helps.
Basically, there are 4 components that are doing API calls:
BreadcrumbBar, Bookmarks, Host's PowerStatus and Statistics.
3 out of them are using ajaxRequestAction - BreadcrumbBar doesn't use ajaxRequestAction probably because of payload structure nuance.

Bookmarks doesn't use any element set in item but does expect error to be the error message - which is fixed in this patch.
Host's PowerStatus and Statistics however are expecting the payload to have id given in item (I guess matan missed that change when he pushed this) so I decided to keep item there and use it in reducers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it would be nicer if I keep the order, though (for a readable diff):

payload: { error: error.message, item }

@@ -32,7 +32,7 @@ class StatisticsChartsList extends React.Component {
chart={chart}
noDataMsg={__('No data available')}
tip={__('Expand the chart')}
errorText={chart.error}
errorText={chart.error ? chart.error.message : ''}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to discard this change, though.

@@ -11,5 +11,5 @@ export const ajaxRequestAction = ({
dispatch({ type: requestAction, payload: item });
return API.get(url)
.then(({ data }) => dispatch({ type: successAction, payload: { ...item, ...data } }))
.catch(error => dispatch({ type: failedAction, payload: { error, item } }));
.catch(error => dispatch({ type: failedAction, payload: { error: error.message, item } }));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have one concern about storing only the error message:
the message property is optional, and could be blank, plus if we'd like to distinct between error types we couldn't do it only with the error's message.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem. We can keep storing the error object but will map from error object to error message on the component side.

Copy link
Member

@amirfefer amirfefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ripcurld looks good !
I left some minor inline comments

Next time just please add a comment after an update :)

@@ -27,4 +27,3 @@ export const onSuccessActions =
payload: mockSuccessRequests[0].response,
type: 'HOST_POWER_STATUS_SUCCESS',
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary deletion

prev: stateBeforeResponse,
action: {
type: types.HOST_POWER_STATUS_FAILURE,
payload: { error, item: { id: request.id } },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we store the entire resource under item ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By saying "entire resource" are you talking about the request?
Basically you want to change this line to

payload: { error, item: request }

Right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a second look, only the id is stored via ajaxRequestAction

'should return the initial state': {
prev: undefined,
action: {},
next: initialState,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally prefer snapshots rather then supply a preconfigured results object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will see what I can do about that.

@boaz0
Copy link
Member Author

boaz0 commented Jun 17, 2018

@sharvit @amirfefer
done! feel free to add more feedback.

@@ -32,7 +32,7 @@ class StatisticsChartsList extends React.Component {
chart={chart}
noDataMsg={__('No data available')}
tip={__('Expand the chart')}
errorText={chart.error}
errorText={(chart.error || {}).message ? chart.error.message : ''}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could errorText remain undefined instead of initialize empty string each render?

errorText={chart.error && chart.error.message}

The FAILURE action dispatched in ajaxRequestAction is not
aligned with the bookmarks, powerStatus and statistics
reducers:
 - Moving to axios returns Error object instead of a string
 - The payload doesn't contain "id" but "item"

This patch fixes that problem and makes components work
on failures from API.

In addition, tests were added and fixed to avoid regressions.

Signed-off-by: Boaz Shuster <boaz.shuster.github@gmail.com>
@boaz0
Copy link
Member Author

boaz0 commented Jun 18, 2018

[test katello]

Copy link
Member

@amirfefer amirfefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@ohadlevy
Copy link
Member

[test katello]

@ohadlevy
Copy link
Member

test failure unrelated. thanks @ripcurld

@ohadlevy ohadlevy merged commit 7d6d573 into theforeman:develop Jun 18, 2018
@boaz0 boaz0 deleted the fixes_23709 branch June 18, 2018 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants