Ensure proper Exception inheritance in APIException subclasses - #9883
Ensure proper Exception inheritance in APIException subclasses#9883RinZ27 wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a gap in exception handling by ensuring that DRF's custom exceptions properly call their parent Exception.__init__() method. This fix ensures that standard exception attributes like args are properly populated, which is important for compatibility with error-tracking tools and logging middleware that rely on these standard attributes.
Changes:
- Updated
APIException.__init__()to callsuper().__init__()with the processed detail - Updated
ValidationError.__init__()to callsuper().__init__()instead of directly settingself.detail
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5a340d9 to
89020ae
Compare
|
@thawancomt It primarily affects interoperability with standard Python tooling. Since For example, a simple |
|
I get it now, thx man |
browniebroke
left a comment
There was a problem hiding this comment.
While DRF handles its own self.detail logic, skipping the base Exception.init leaves exc.args empty. This can cause issues with error-tracking tools or logging middleware that expect standard exception attributes.
I'm not sure I follow, here is what I'm getting on main:
>>> from rest_framework.exceptions import *
>>> e = ValidationError("Invalid input")
>>> e.args
('Invalid input',)
>>> e2 = APIException("test", 123)
>>> e2.args
('test', 123)So it seems to me that exc.args is set properly?
After a quick query, this is apparently set by BaseException.__new__, not Exception.__init__...
As far as I can tell, we don't need this change. Unless. you wanted to do something else?
| code = self.default_code | ||
|
|
||
| self.detail = _get_error_details(detail, code) | ||
| super().__init__(self.detail) |
There was a problem hiding this comment.
Not passing down the code to this one? This changes the representation of the exception in the REPL and make it quite verbose:
Before
>>> APIException("Invalid input", 400)
APIException('Invalid input', 400)
After
>>> APIException("Invalid input", 400)
APIException(ErrorDetail(string='Invalid input', code=400))
| detail = [detail] | ||
|
|
||
| self.detail = _get_error_details(detail, code) | ||
| super().__init__(self.detail, code) |
There was a problem hiding this comment.
Similar comment on verbosity.
Before
>>> ValidationError("Invalid input", 400)
ValidationError('Invalid input', 400)
After
>>> ValidationError("Invalid input", 400)
ValidationError([ErrorDetail(string='Invalid input', code=400)])
|
@browniebroke You're right, and I appreciate you taking the time to actually test it. Closing this one. |
I noticed that
APIExceptionandValidationErrorwere overriding__init__without callingsuper().__init__(). While DRF handles its ownself.detaillogic, skipping the baseException.__init__leavesexc.argsempty. This can cause issues with error-tracking tools or logging middleware that expect standard exception attributes.This change ensures that all DRF exceptions properly populate their base attributes while maintaining existing functionality. I've updated the initialization chain to ensure
super()is called correctly throughout.