Conversation
… rework (#968) * Surface the real reason when Creator journey completion fails Users who fail to complete the Creator journey currently hit an opaque HTML 500 that the portal can only render as a generic "try again" dead end, and the reports keep coming with nothing actionable in them. The community completion endpoint now catches unhandled errors the same way the builder endpoint does: the role grant still rolls back, the client receives the actual failure reason as JSON (which the portal already displays verbatim), and the full traceback is written to the logs. Builder journey completion logging now keeps the traceback as well instead of only the exception message. ## Claude Implementation Notes - backend/users/views.py: Wrapped complete_community_journey's transaction and success response in try/except returning a JSON 500 with the real error, logged via logger.exception (catching suppresses django.request's own 500 traceback logging). Switched complete_builder_journey's logger.error to logger.exception for the same reason. - backend/users/tests/test_community_journey.py: New test patches update_user_leaderboard_entries to raise during the POST only (setup-step signals call the same function) and asserts JSON 500 with the reason, an ERROR log, and Creator rollback. * Assert the completion failure log carries the traceback The failure test only proved an ERROR record was emitted, so reverting logger.exception to a bare logger.error(str(e)) would still pass while losing the diagnostic traceback this change exists to keep. The test now captures the log output and requires both the traceback and the original exception text in it. ## Claude Implementation Notes - backend/users/tests/test_community_journey.py: Capture the assertLogs context in test_complete_failure_returns_json_error_and_rolls_back and assert 'Traceback' and the exception message appear in the joined output. * Fix new Creator and Builder role grants failing at the final step Since the June onboarding rework, every first-time role grant through the Creator and Builder journeys failed in production while all tests passed. The completion endpoints re-fetched the user via type(request.user), and in production request.user is Django's lazy wrapper: every attribute access proxies to the real user, but the wrapper's type has no .objects manager, so the grant crashed and rolled back on the exact line that only runs for genuinely new members. Tests authenticated with a concrete user, which is why the suite never saw it. Both endpoints now resolve the model through get_user_model(), and each journey gains a completion test that runs through the real session authentication chain so the wrapper shape is covered from now on. ## Claude Implementation Notes - backend/users/views.py: Replace type(user).objects with get_user_model().objects in complete_builder_journey and complete_community_journey; comments explain the SimpleLazyObject trap. Confirmed against the production CloudWatch traceback (AttributeError: type object 'SimpleLazyObject' has no attribute 'objects' at the fresh_user re-fetch). - backend/users/tests/test_community_journey.py: test_complete_grants_creator_through_wallet_session_auth completes the journey via login_wallet_session; reproduced the production 500 before the fix. - backend/users/tests/test_builder_journey.py: test_complete_grants_role_through_wallet_session_auth, same pattern for the builder grant. - backend/CLAUDE.md: New "request.user is a lazy wrapper" section documenting the trap and the wallet-session test guards. * Update changelog * Keep exception internals out of journey completion error responses A failed role grant returned str(exception) to the client, and the portal renders those fields verbatim. Database error text can carry table and constraint names or even the conflicting row values, so the client now gets a stable completion_failed code with a friendly message while the full traceback stays in the server logs, which today's diagnosis proved is the channel that matters. ## Claude Implementation Notes - backend/users/views.py: Both journey completion except blocks return {'error': 'completion_failed', 'message': ...} instead of interpolating str(e); logger.exception unchanged. The frontend completionErrorMessage helpers pick up data.message, so no frontend change is needed. - backend/users/tests/test_community_journey.py: The failure test now asserts the stable error code and that the exception text does NOT appear anywhere in the response, while still requiring it in the logged traceback. * Show tracebacks in the dev console log format logger.exception call sites are the only durable traceback source once a view catches an error, and the production JSON formatter already renders them. The human-readable console formatter used in development dropped exc_info entirely, leaving a bare one-line ERROR. It now appends the formatted traceback, and both formatters have a direct test pinning the exception rendering. ## Claude Implementation Notes - backend/tally/middleware/logging_utils.py: LayeredFormatter.format appends self.formatException(record.exc_info) when present, matching LayeredJSONFormatter's behavior. - backend/tally/tests/test_logging_formatters.py: New direct tests asserting both formatters include the traceback and exception text.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
… rework (#968)
Users who fail to complete the Creator journey currently hit an opaque HTML 500 that the portal can only render as a generic "try again" dead end, and the reports keep coming with nothing actionable in them. The community completion endpoint now catches unhandled errors the same way the builder endpoint does: the role grant still rolls back, the client receives the actual failure reason as JSON (which the portal already displays verbatim), and the full traceback is written to the logs. Builder journey completion logging now keeps the traceback as well instead of only the exception message.
Claude Implementation Notes
The failure test only proved an ERROR record was emitted, so reverting logger.exception to a bare logger.error(str(e)) would still pass while losing the diagnostic traceback this change exists to keep. The test now captures the log output and requires both the traceback and the original exception text in it.
Claude Implementation Notes
Since the June onboarding rework, every first-time role grant through the Creator and Builder journeys failed in production while all tests passed. The completion endpoints re-fetched the user via type(request.user), and in production request.user is Django's lazy wrapper: every attribute access proxies to the real user, but the wrapper's type has no .objects manager, so the grant crashed and rolled back on the exact line that only runs for genuinely new members. Tests authenticated with a concrete user, which is why the suite never saw it. Both endpoints now resolve the model through get_user_model(), and each journey gains a completion test that runs through the real session authentication chain so the wrapper shape is covered from now on.
Claude Implementation Notes
Update changelog
Keep exception internals out of journey completion error responses
A failed role grant returned str(exception) to the client, and the portal renders those fields verbatim. Database error text can carry table and constraint names or even the conflicting row values, so the client now gets a stable completion_failed code with a friendly message while the full traceback stays in the server logs, which today's diagnosis proved is the channel that matters.
Claude Implementation Notes
logger.exception call sites are the only durable traceback source once a view catches an error, and the production JSON formatter already renders them. The human-readable console formatter used in development dropped exc_info entirely, leaving a bare one-line ERROR. It now appends the formatted traceback, and both formatters have a direct test pinning the exception rendering.
Claude Implementation Notes