Skip to content

Conversation

fsbraun
Copy link
Member

@fsbraun fsbraun commented Jan 25, 2025

Description

fixes #7974

Since django CMS 4, exceptions that happen during plugin rendering have been caught and displayed a message at the plugin's position.

After feedback from the community, this PR refactors error handling when rendering placeholders.
.

  • Exceptions are now caught on placeholder level.

  • In edit mode, a message about the exception is shown for the placeholder. If settings.DEBUG == True this message includes the full Django trace.

  • Editors still can edit plugins causing the exception. It can be edited by double-clicking the error message or through the structure board.

  • In preview mode and on site, the placeholder containing the plugin will render empty.

  • If settings.CMS_CATCH_PLUGIN_500_EXCEPTION is set to False, trying to view content that raises an exception will trigger a server error (http 500). Preview and edit modes will still work.

Screenshot

This is a full error message in edit mode and with DEBUG = True. The plugin with pk 35 caused a division by zero exception. It can be edited by double-clicking the red error message. Toolbar and structure board are available.

image

The same warning message on a production system is shorter:
image

Related resources

Checklist

  • I have opened this pull request against develop-4
  • I have added or modified the tests when changing logic
  • I have followed the conventional commits guidelines to add meaningful information into the changelog
  • I have read the contribution guidelines and I have joined the channel #pr-reviews on our Discord Server to find a “pr review buddy” who is going to review my pull request.

Summary by Sourcery

Bug Fixes:

  • Fix error handling when rendering placeholders.

Copy link
Contributor

sourcery-ai bot commented Jan 25, 2025

Reviewer's Guide by Sourcery

This pull request refactors error handling when rendering placeholders. It introduces a try-except block to catch exceptions during plugin rendering and template rendering, and logs the error. It also adds a visual representation of the error in the CMS when in edit mode.

Sequence diagram for placeholder error handling flow

sequenceDiagram
    participant CMS as CMS System
    participant Renderer as ContentRenderer
    participant Plugin as Plugin Instance
    participant Template as Template Engine
    participant Logger as Error Logger

    CMS->>Renderer: render_placeholder()
    activate Renderer
    Renderer->>Plugin: render_plugin()
    activate Plugin
    alt Successful rendering
        Plugin-->>Renderer: rendered content
    else Exception occurs
        Plugin-->>Renderer: throws exception
        Renderer->>Logger: log error
        alt Edit mode active
            Renderer-->>CMS: error visualization
        else Production mode
            alt CATCH_PLUGIN_500_EXCEPTION enabled
                Renderer-->>CMS: empty content
            else
                Renderer-->>CMS: re-raise exception
            end
        end
    end
    deactivate Plugin
    deactivate Renderer
Loading

Class diagram for renderer error handling

classDiagram
    class BaseRenderer {
        +render_placeholder()
        +render_plugin()
    }
    class ContentRenderer {
        +render_exception(action, context, placeholder, editable)
        +render_placeholder()
        +render_plugin()
    }
    class StructureRenderer {
        +render_placeholder()
        +render_plugin()
    }
    class LegacyRenderer {
        +render_placeholder()
        +get_editable_placeholder_context()
    }

    BaseRenderer <|-- ContentRenderer
    BaseRenderer <|-- StructureRenderer
    ContentRenderer <|-- LegacyRenderer

    note for ContentRenderer "New error handling logic"
Loading

File-Level Changes

Change Details Files
Refactor error handling during placeholder rendering.
  • Added try-except block to catch exceptions during plugin rendering.
  • Added try-except block to catch exceptions during template rendering.
  • Added a render_exception method to handle exceptions and return a user-friendly error message.
  • Added logging of exceptions during plugin and template rendering.
  • Added logic to display error messages in the CMS when in edit mode.
  • Added logic to raise exceptions when not in edit or preview mode, and the CATCH_PLUGIN_500_EXCEPTION setting is False.
cms/plugin_rendering.py
Add tests for the new error handling logic.
  • Added tests to verify that exceptions during plugin rendering are caught and logged.
  • Added tests to verify that exceptions during template rendering are caught and logged.
  • Added tests to verify that error messages are displayed in the CMS when in edit mode.
  • Added tests to verify that exceptions are raised when not in edit or preview mode, and the CATCH_PLUGIN_500_EXCEPTION setting is False.
cms/tests/test_plugin_renderers.py
Add styles for the error messages in the CMS.
  • Added styles for the error messages displayed in the CMS when in edit mode.
cms/static/cms/sass/components/_general.scss
Add a setting to control whether plugin exceptions should be caught.
  • Added a CATCH_PLUGIN_500_EXCEPTION setting to control whether plugin exceptions should be caught.
cms/utils/conf.py

Assessment against linked issues

Issue Objective Addressed Explanation
#7974 Introduce a new setting to control exception handling for plugins in production vs edit/preview modes
#7974 Ensure that in edit and preview modes, full plugin errors are visible to help developers debug
#7974 Allow optional HTTP 500 generation for plugin exceptions in production when the new setting is disabled

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@fsbraun fsbraun marked this pull request as ready for review January 25, 2025 20:56
@fsbraun
Copy link
Member Author

fsbraun commented Jan 25, 2025

@florianschieder Please comment.

@fsbraun fsbraun requested a review from vinitkumar January 25, 2025 21:00
@marksweb
Copy link
Member

Looks good on a first glance 👍

Copy link
Member

@vinitkumar vinitkumar left a comment

Choose a reason for hiding this comment

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

Looks good to me. Let's get this merged.

@vinitkumar vinitkumar merged commit 8274ff6 into django-cms:develop-4 Jan 27, 2025
51 checks passed
@florianschieder
Copy link
Contributor

@florianschieder Please comment.

@fsbraun Looks great! Thank you very much for the helpful solution!

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.

Change behaviour or how exceptions are silently caught in production and edit mode
4 participants