如何在Python中禁用异常链?Django测试场景下冗余异常信息处理及原理疑问
Great question! Let’s break this down into two parts: fixing the redundant traceback output, and explaining why Python automatically links the original exception even without explicit raise ... from syntax.
Fixing the Traceback: Cut the Exception Chain
To make Python only show your custom exception and hide the original SystemExit traceback, you can use the raise ... from None syntax. This explicitly tells Python to break the connection between the original exception and your new one.
Here's your modified test code:
from django.test import TestCase from django.core.management import call_command class MigrationsCreatedTest(TestCase): def test_migrations_created(self): try: call_command("makemigrations", "--check", "--dry-run") except SystemExit: # Use `from None` to suppress the original exception context raise Exception("There are migrations that have not been created!") from None
With this change, when your test fails, the traceback will only show your custom error message, no extra SystemExit details:
====================================================================== ERROR: test_migrations_created (tests.test_migrations_created.MigrationsCreatedTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/user/ahs-project/website/tests/test_migrations_created.py", line 16, in test_migrations_created raise Exception("There are migrations that have not been created!") from None Exception: There are migrations that have not been created!
Why Python Automatically Links the Original Exception
You’re correct that raise ... from exc creates an explicit causal link (setting the exception’s __cause__ attribute). But in Python 3, there’s also an implicit context link that happens by default when you raise a new exception inside an except block.
When you catch an exception and raise another one without using from, Python sets the new exception’s __context__ attribute to the original exception. This is designed to preserve debugging context in case you need to trace back why the new exception was triggered. The traceback shows this with the line: "During handling of the above exception, another exception occurred:"
Using from None overrides this behavior: it sets the new exception’s __context__ to None, so Python won’t include the original exception’s traceback in the output.
内容的提问来源于stack exchange,提问作者John

