-
Notifications
You must be signed in to change notification settings - Fork 783
fix(repository): fix repo view when repos return 404 #726
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
fix(repository): fix repo view when repos return 404 #726
Conversation
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.
@dhamanutd Great new feature! Waiting for your feedbacks about my comments.
@@ -49,6 +49,7 @@ const mapStateToProps = state => ({ | |||
isPendingTopics: state.repository.isPendingTopics, | |||
isPendingSubscribe: state.repository.isPendingSubscribe, | |||
topics: state.repository.topics, | |||
notFoundMsg: state.repository.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.
Personally, I prefer errorMessage
or error
directly. Then we can handle other types of errors and other information about errors in the future.
underlayColor={colors.greyLight} | ||
disabled={(notFoundMsg && true) || false} |
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.
disabled={!!notFoundMsg}
will be simpler.
@@ -12,6 +12,7 @@ type Props = { | |||
loading: boolean, | |||
subscribed: boolean, | |||
locale: string, | |||
notFoundMsg: string, |
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 notFoundMsg
is an inner state, which will not be customized from outside frequently. So we can add a new prop called error
, hasError
, or simply determinate it by repository.name
.
@@ -133,7 +135,7 @@ export const RepositoryProfile = ({ | |||
)} | |||
|
|||
<Text style={[styles.languageInfoTitle]}> | |||
{repository.language || ' '} | |||
{notFoundMsg || repository.language || ' '} |
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.
Try to add a new field in all files of locale/languages
, say repository.unknowLanguage
or something else you think better. Then rewrite as,
repository.language || translate('repository.unknowLanguage', locale)
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.
@chinesedfan can i use google translate for another translation?
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.
@dhamanutd No, please just leave them in English. Other contributors will pick them up and translate.
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.
Nice feature. Just an observation, the key has a typo, should be unknownLanguage
.
(notFoundMsg && 'stop') || | ||
(repository.fork && 'repo-forked') || | ||
'repo' | ||
} |
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.
As we forbid nested ternary expressions, please extract as a function to make it more readable.
type="octicon" | ||
size={45} | ||
color={colors.greyLight} | ||
/> | ||
|
||
<Text style={styles.title}>{repository.name || ' '}</Text> | ||
<Text style={styles.title}>{notFoundMsg || repository.name || ' '}</Text> |
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.
Similar here.
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.
is that mean, you want make "Unkown" or "Not Found" as default, right?
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.
My point is that the current "Not Found" is a message returned by Github API. Setting it as the value of Text directly will make the usage of this Text unclear. We'd better,
- declare a corresponding string constant to represent special repository name, as I said before
- or, create another certain UI component (maybe like a Toast) to show it
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.
@chinesedfan if want to use Toast, i will install library react-native-simple-toast. What do you think? does it needed? Because toast from react native didn't support iOS
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.
Sure, I don't mind to introduce a new library as long as it is useful. And we can also wait for some feedbacks from other reviewers, like @machour.
src/api/index.js
Outdated
return response.json(); | ||
return response.ok | ||
? response.json() | ||
: response.json().then(err => Promise.reject(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.
In fact, response.json().then(err => Promise.reject(err))
is the same with response.json()
. You handle the error in then
and throw out identically. Please correct me if I misunderstood your thinking.
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.
@chinesedfan
this because when the response status is 4xx it always handled by .then()
, that's why i give return Promise.reject
to make it handled by .catch()
. But if you think there better way to distinct beetween 200 OK and 4xx Error, let me know.
Another suggestion from me is to implement Axios and Redux-Saga to the app for better handling failures.
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.
@dhamanutd I see. Then you can modify getRepository
to call v3.call
, and check response.status
. Please refer to checkReadMe
.
instead of blank view, now will show not found message when error 404 BREAKING CHANGE: fix repository view when the repos 404 not found fix gitpoint#690
simpler ternary and change nested ternary to a function instead, delete props that not needed anymore.
repository.main.unknowLanguage and repository.main.notFoundRepo
a7520f5
to
440d091
Compare
give logical promise in the getRepository action reducer and add new state.repository.hasRepoExist
to make Toast also supported in iOS.
@chinesedfan i did some of you requested to changes. you can review it now. |
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.
@dhamanutd Thanks for your fast update! We are almost there.
src/repository/repository.action.js
Outdated
json = response.json().then(err => Promise.reject(err)); | ||
} | ||
|
||
return json; |
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.
How about writing in one line, return response.status === 200 ? response.json() : Promise.reject()
?
@@ -39,6 +40,7 @@ const mapStateToProps = state => ({ | |||
starred: state.repository.starred, | |||
forked: state.repository.forked, | |||
subscribed: state.repository.subscribed, | |||
hasRepoExist: state.repository.hasRepoExist, |
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.
Shall we keep hasRepoExist
and error
together? Or either is enough?
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.
Actually i want to remove error
. But as you said before, you said maybe it will be used in future.
So, will me to delete that?
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 prefer to keep error
, because error
is needed for Toast, while hasRepoExist
can be replaced by !error
. What do you think about?
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.
@chinesedfan i think hasRepoExist
is only to set state if repo exist or not, but error
is to get value whatever it is not only about repo exist or not. I think both are used.
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.
Yes, there are tricky differences between them. It requires us to handle these 2 fields more carefully.
src/locale/languages/en.js
Outdated
@@ -177,6 +177,8 @@ export const en = { | |||
}, | |||
repository: { | |||
main: { | |||
notFoundRepo: 'Repository is not found', | |||
unknowLanguage: 'Unknown', |
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.
unknownLanguage
as @arthurdenner suggested? Sorry I am not a native English speaker.
edit typo in translation simpler conditional to ternary, also edit fetchRepoInfo() promise to .finally() instead of .then()
error: action.payload, | ||
isPendingRepository: false, |
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 just noticed that this line was removed. Do you want to keep pending state when an error occurs?
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.
@chinesedfan it's because we take ...initialState
that already had isPendingRepository
state as false
.
src/repository/repository.reducer.js
Outdated
@@ -62,19 +63,21 @@ export const repositoryReducer = (state = initialState, action = {}) => { | |||
return { | |||
...state, | |||
issues: [], | |||
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.
If you persist to keep 2 fields, I suggest to clear hasRepoExist
when pending and error. If repo1 set it to be true
, then repo2 will get wrong value during pending or 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.
@chinesedfan in current changes, i've tried to test in real world. I don't face any problem when openning from one repo to another.
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.
Yes, as you reset with initialState
, the error state is cleared. And the pending state is too fast to be noticed.
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.
Understand, okay i will set hasRepoExist
when pending too
src/repository/repository.action.js
Outdated
.then(response => { | ||
return response.status === 200 | ||
? response.json() | ||
: response.json().then(err => Promise.reject(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.
response.json()
will never throw an error, no matter response.status === 200
or not, right? So I think Promise.reject()
is enough. We don't need to call response.json()
again.
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.
@chinesedfan if we just only using Promise.reject()
, we will not pass any value from that. It will just call .catch()
but didn't pass any data you get from API response. In this case we will not get the "Not Found" messages from github API.
That's why first i need to get json()
data from API, then i pass that data in the Promise.reject(err)
.
I make both if true (equal 200) or false (not equal 200) will send same json formatted data.
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.
@dhamanutd Oh, hope I understand your idea this time. Do you mean response.json().then((json) => response.status === 200 ? json : Promise.reject(json))
?
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.
@chinesedfan yes, that's what i'm intended to
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.
Good. Can you update it? Then I think there are no problems from my side. Thanks for your patient revisions!
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.
@chinesedfan done
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 great, thank you @dhamanutd :)
Just wanted to ask - how does the Toast show on Android? Can check it as well if we merge this in
@@ -740,6 +740,15 @@ | |||
"contributions": [ | |||
"code" | |||
] | |||
}, | |||
{ | |||
"login": "dhamanutd", |
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.
🎉 🚀 🚀
instead of blank view, now will show not found message when error 404
BREAKING CHANGE: fix repository view when the repos 404 not found
fix #690
Screenshots
Description
getRepository
to return Promise reject when response status code is not 200 OKnotFoundMsg
props in the repository screen and component to take string from github api when return 404.GET_REPOSITORY.ERROR
to return initialState instead of recent state.