Repository navigation
fix(recaptcha): demo views answered 500 instead of their JSON error body - #14635
rootkiller6788 wants to merge 1 commit into
Conversation
`except ValueError or Exception as e` reads like it catches both, but `or`
returns the first truthy operand, so the handler only ever caught
ValueError. Anything else escaped it: the assessment call raises
google.api_core errors (PermissionDenied, InvalidArgument, ...) which are
not ValueError, and a request body without "token" raises KeyError before
the call is even made.
All four submit views were written to answer with
{"data": {"error_msg": ...}} in that case, so they were returning a 500
error page instead. Exception already covers ValueError, so the tuple is
not needed.
Signed-off-by: rootkiller6788 <rootkiller6788@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request simplifies exception handling in several endpoints of the recaptcha enterprise demosite by replacing the incorrect 'except ValueError or Exception as e' syntax with 'except Exception as e'. The review feedback correctly points out that using 'str(e.dict)' to serialize the exception will result in an empty dictionary string for standard Python exceptions, and suggests using 'str(e)' instead to properly capture and return the error message.
| except Exception as e: | ||
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) |
There was a problem hiding this comment.
Using str(e.__dict__) typically returns an empty dictionary string ('{}') for standard Python exceptions because they do not store their error messages in __dict__. To return the actual error message, use str(e) instead.
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) | |
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e)}}) |
| except Exception as e: | ||
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) |
There was a problem hiding this comment.
Using str(e.__dict__) typically returns an empty dictionary string ('{}') for standard Python exceptions because they do not store their error messages in __dict__. To return the actual error message, use str(e) instead.
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) | |
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e)}}) |
| except Exception as e: | ||
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) |
There was a problem hiding this comment.
Using str(e.__dict__) typically returns an empty dictionary string ('{}') for standard Python exceptions because they do not store their error messages in __dict__. To return the actual error message, use str(e) instead.
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) | |
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e)}}) |
| except Exception as e: | ||
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) |
There was a problem hiding this comment.
Using str(e.__dict__) typically returns an empty dictionary string ('{}') for standard Python exceptions because they do not store their error messages in __dict__. To return the actual error message, use str(e) instead.
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e.__dict__)}}) | |
| except Exception as e: | |
| return jsonify({"data": {"error_msg": str(e)}}) |
Found this while reading the reCAPTCHA Enterprise demosite.
All four submit handlers end with
except ValueError or Exception as e. That doesn't do what it looks like:orreturns the first truthy operand, so the handler only ever catchesValueError. Everything else goes straight past it and the endpoint answers with a 500 error page instead of the{"data": {"error_msg": ...}}it was written to return.Easy to hit in practice - the assessment call raises google.api_core errors like PermissionDenied/InvalidArgument, which aren't ValueError, and a request body without "token" raises KeyError before the call is even made.
Changed the four handlers to
except Exception(Exception already covers ValueError, so no tuple needed).How I checked: pointed
create_assessmentat something that raises PermissionDenied and drove the views with Flask's test client. Before: all four returned 500. After: all four return 200 with the JSON error body. Same for a payload missing "token".One thing I noticed but left alone to keep the diff on the actual bug:
str(e.__dict__)on the next line gives an empty dict for errors that carry no attributes, soerror_msgcan come out as{}.Signed-off-by: rootkiller6788 rootkiller6788@users.noreply.github.com