Respond with 404 Not Found if project not found in Api::SchoolProjectsController actions #564
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Previously when a request was made to either of the actions in
Api::SchoolProjectsControllerfor a project that does not exist, the following exception was raised, because the call toProject.find_byreturnednil:Unhandled exceptions are rescued by the default
ActionDispatch::ShowExceptionsmiddleware. In turn this uses the default exceptions app,ActionDispatch::PublicExceptionsto render a static HTML error page frompublic/500.htmlin this case.Since this is an API endpoint, ideally it should always respond with JSON in the response body, otherwise it makes writing client code a lot harder. Indeed my actual motivation for fixing this is, because we've been seeing
JSON:ParseErrorexceptions raised in experience-cs.I've fixed the problem by using
Project.find_by!instead ofProject.find_by. This means that if the project is not found, aActiveRecord::RecordNotFoundexception is raised. This in turn is rescued by therescue_fromblock inApiControllerand the action responds with a404 Not Foundhead response, i.e. with no body.This head response seems to be handled OK by the HTTParty code in experience-cs and thus it fixes the problem I was trying to address.
The equivalent client-side code in editor-standalone was already throwing an
AxiosErrorexception due to the500response code (not being a2XXcode) and it will continue to throw the same exception, albeit with a payload reflecting the response code being404instead of500and the body being empty instead of being the Rails500HTML error page.There is no specific error-handling code in editor-standalone catching this exception, so I assume it's just relying on the generic error handling for the React app. Thus I think the user-facing behaviour should be unchanged.
Addresses https://github.com/RaspberryPiFoundation/experience-cs/issues/828.
Postscript
While investigating this issue, I've uncovered a number of other problems with the
Api::SchoolProjectsControllercode and its specs, but I've intentionally not addressed them here in order to keep the scope of this PR as small as possible and keep it focussed on fixing the problem at hand. However, in case it's useful, I'll list the issues here:load_and_authorize_resource :projectis not working as intended:Projectinstance (even if it was, it would be attempting to callProject.find(params[:id)and notProject.find_by!(identifier: params[:id])Project(it seems to be authorizing the user canshowtheProjectclass, but it seems unlikely this is what was intended)load_and_authorize_resourcewas added and no tests fail if I remove it!Api::ProjectsControlleruses a customProjectLoaderclass which takeslocaleinto account, I would've thought that thisApi::SchoolProjectsControllershould also use the same lookup mechanism, but it doesn't.before_action :authorize_usercall.ProfileApiMock#stub_profile_api_list_school_studentsinspec/requests/school_projects/show_finished_spec.rb&spec/requests/school_projects/set_finished_spec.rbseem unnecessary and are potentially confusing. This helper method stubsProfileApiClient.list_school_students, but this method is never called by code exercised by those specs. This seems to be a wider problem where calls toProfileApiMock#stub_profile_api_list_school_studentshave been added to specs that don't need it. Perhaps they never needed it or the need for them has gone away.lib/concepts/*/operations/are usually rescued and the action responds with a JSON body. However, for exceptions that occur outside those operations (e.g. in the actions themselves) just result in the 500 error with HTML body.