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

Fix: uploads.json endpoint returns 500 internal server error for some courses#6046 #6114

Conversation

empty-codes
Copy link
Contributor

@empty-codes empty-codes commented Jan 13, 2025

What this PR does

Fixes the apparent cause of the 500 Internal server error in Issue #6046 and the subsequent TypeError it causes.

Note: I could not replicate the error on my dev as only 138 uploads were imported out of the around 7000 after running updates multiple times. The 138 uploads loaded without error for me which I assume is because the problematic upload / file name File%3AA+sunflower+%F0%9F%8C%BB%F0%9F%8C%BB+in+Kaduna+Polytechnic%2CSabo+Campus.jpg was not imported.

The commons link is here. It was uploaded by a user ‘Bambi Cia’ who has apparently deleted their user page / account. Trying to view their profile with this link, just shows loading: https://outreachdashboard.wmflabs.org/users/Bambi Cia because this request throws a 500 internal server error too: https://outreachdashboard.wmflabs.org/user_stats.json?username=Bambi Cia {"message":"Internal server error"}.

I used the test to verify this fix, and ran the updated code locally + used chrome dev tools to verify the TypeError fix works and doesn't break anything.

Fixing the 500 Error by allowing decoding of encoded strings

To fix this, I added CGI.unescape to decode such url encoded strings to their original formats:

pretty = CGI.unescape(upload.file_name)

I then added another test in the uploads_helper_spec.rb to confirm it works.

Before:
b4

After:
afta

Fixing the resulting TypeError

image

When a 500 error occurs, the flow goes through the .catch() block inside the fetchUploads function, and resp is logged there. However, when the control goes back to the .then() block, resp is undefined because the promise is rejected and there is no valid response object passed.

Then when the case RECEIVE_UPLOADS is reached in the uploads.js reducer, the action.data will be undefined, and trying to access action.data.course.uploads throws the TypeError: Cannot read properties of undefined('reading course'.

To prevent this, I:

  • Added the optional chaining operator ?. with a fallback to [] so instead of throwing a TypeError when trying to access .course on undefined or .uploads on undefined, it evaluates to undefined. So if action.data?.course?.uploads evaluates to undefined (because any part of the chain is missing), [] is assigned to dataUploads:
    const dataUploads = action.data?.course?.uploads || [];

So when dataUploads is [], sortByKey will return an empty array for newModels, and the reducer will update the state with an empty uploads array.

I also:

  • Expanded the error handling in fetchUploads as when the 500 error occurs, res does not hold any relevant info other than the status being 500, (the status.text is an empty string) and Error: undefined is what is logged in the console.

  • Added an explicit check for if resp is undefined, to explicitly state 'No response received.'

… some courses:

- Uses `CGI.unescape` to decode url encoded string to their original formats if applicable thus solving cause of 500 error
- Improves error handling in js actions and reducers to not result in TypeErrors when a 500 error (or any other error) occurs
@ragesoss ragesoss merged commit 3938a93 into WikiEducationFoundation:master Jan 13, 2025
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants