Skip to content

[GIT-213] fix: return HTTP response from dispatch() exception handler#9179

Open
sriramveeraghanta wants to merge 1 commit into
previewfrom
fix/git-213-dispatch-returns-response
Open

[GIT-213] fix: return HTTP response from dispatch() exception handler#9179
sriramveeraghanta wants to merge 1 commit into
previewfrom
fix/git-213-dispatch-returns-response

Conversation

@sriramveeraghanta
Copy link
Copy Markdown
Member

@sriramveeraghanta sriramveeraghanta commented May 30, 2026

Description

When an API request triggered an unhandled exception, the shared view bases caught it, built the proper error Response via handle_exception(), but then returned the raw exception object instead of the response:

except Exception as exc:
    response = self.handle_exception(exc)
    return exc          # ← should be `return response`

Django's response pipeline then failed with TypeError: 'Exception' object is not a valid HTTP response, so clients received a malformed 500 with no structured body instead of a clean JSON error.

The same copy-pasted defect existed in six dispatch() methods across four files, so this PR fixes all of them — not only the one reported in the issue — so the crash cannot surface from the external API, app, space, or license surfaces:

  • apps/api/plane/api/views/base.pyBaseAPIView
  • apps/api/plane/app/views/base.pyBaseViewSet, BaseAPIView
  • apps/api/plane/license/api/views/base.pyBaseAPIView
  • apps/api/plane/space/views/base.pyBaseViewSet, BaseAPIView

(api.BaseViewSet already returned response correctly, which confirmed the intended fix.)

A parametrized regression test covers every affected base class and asserts that, when super().dispatch() raises, dispatch() returns an HTTP Response rather than the exception.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Test Scenarios

  • Added apps/api/plane/tests/unit/views/test_base_dispatch.py: parametrized over all six affected base classes plus api.BaseViewSet as a control; asserts dispatch() returns a rest_framework.response.Response (not the exception) when super().dispatch() raises. Verified RED (6 failures) before the fix and GREEN (7 passing) after.
  • Full API suite via docker compose -f docker-compose-test.yml up --build --abort-on-container-exit --exit-code-from api-tests: 236 passed (exit code 0), including DB-backed contract/model/serializer tests.
  • ruff check passes on all changed files.
  • Manual: trigger any API endpoint that raises an unhandled exception and confirm the client receives a structured {"error": ...} JSON body with a 500 status instead of a crashed response pipeline.

References

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed exception handling in API request dispatching to ensure consistent error responses. API callers now receive properly formatted error payloads with appropriate status codes instead of raw exception objects.
  • Tests

    • Added regression tests to verify exception handling behavior is correctly implemented across multiple API view implementations.

Review Change Stack

BaseAPIView.dispatch() and BaseViewSet.dispatch() built the proper
error Response via handle_exception() but returned the raw exception
object instead, causing Django to raise
"TypeError: 'Exception' object is not a valid HTTP response".

Fix all six occurrences across the api, app, license and space view
bases, and add a regression test covering every affected base class.

Fixes #9157
Copilot AI review requested due to automatic review settings May 30, 2026 18:22
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 19c2814e-2303-427a-9ac2-8ba6c3bba993

📥 Commits

Reviewing files that changed from the base of the PR and between 248f5d6 and 97f5e4f.

📒 Files selected for processing (6)
  • apps/api/plane/api/views/base.py
  • apps/api/plane/app/views/base.py
  • apps/api/plane/license/api/views/base.py
  • apps/api/plane/space/views/base.py
  • apps/api/plane/tests/unit/views/__init__.py
  • apps/api/plane/tests/unit/views/test_base_dispatch.py

📝 Walkthrough

Walkthrough

The PR fixes a critical bug across Plane's API base view classes where dispatch() methods return raw exception objects instead of properly formatted HTTP responses, breaking Django's response pipeline. Changes return the result of handle_exception(exc) in exception paths and response in success paths across four modules, plus adds a regression test.

Changes

Dispatch Exception Handling Correction

Layer / File(s) Summary
Core dispatch exception and success-path returns
apps/api/plane/api/views/base.py, apps/api/plane/app/views/base.py, apps/api/plane/license/api/views/base.py, apps/api/plane/space/views/base.py
All four base view modules fixed: exception handler paths now return processed response from handle_exception() instead of raw exception, and success paths return computed response instead of exception variable.
Regression test for dispatch exception handling
apps/api/plane/tests/unit/views/test_base_dispatch.py
New parametrized unit test verifies dispatch() returns the result of handle_exception() when super().dispatch() raises an exception, and does not return the raw exception object.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • #8932: Identical bug fix in the same dispatch() implementations, replacing erroneous return exc with return response.

Poem

🐰 A rabbit hops through error paths,
Where responses went astray,
Now dispatch() returns the proper shape,
No exceptions in the way!
HTTP flows so clean and bright,
The pipeline's fixed—all right! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: returning the HTTP response instead of the exception object from dispatch() exception handlers.
Description check ✅ Passed The description comprehensively covers the bug, affected files, solution approach, test coverage, and verification steps following the repository's template structure.
Linked Issues check ✅ Passed The PR fully addresses issue #9157 by fixing all six affected dispatch() methods to return the HTTP Response instead of the exception object, including comprehensive regression testing.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the dispatch() exception handling bug across all affected base classes and include only necessary regression test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/git-213-dispatch-returns-response

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@makeplane
Copy link
Copy Markdown

makeplane Bot commented May 30, 2026

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a copy-pasted bug in six dispatch() methods across four base view modules where the raw exception was returned instead of the HTTP Response produced by handle_exception(), causing Django's response pipeline to fail with TypeError: 'Exception' object is not a valid HTTP response.

Changes:

  • Replace return exc with return response in the exception handler of dispatch() for BaseAPIView/BaseViewSet across api, app, license, and space view bases.
  • Add a parametrized regression unit test covering all affected base classes plus the already-correct api.BaseViewSet as a control.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
apps/api/plane/api/views/base.py Return Response from BaseAPIView.dispatch() exception path.
apps/api/plane/app/views/base.py Return Response from BaseViewSet/BaseAPIView dispatch() exception paths.
apps/api/plane/license/api/views/base.py Return Response from BaseAPIView.dispatch() exception path.
apps/api/plane/space/views/base.py Return Response from BaseViewSet/BaseAPIView dispatch() exception paths.
apps/api/plane/tests/unit/views/test_base_dispatch.py Parametrized regression test asserting dispatch() returns the Response, not the exception.
apps/api/plane/tests/unit/views/init.py New empty package init for the test directory.

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.

dispatch() Returns Exception Object Instead of HTTP Response in BaseAPIView

2 participants