Opened 16 years ago
Closed 10 years ago
#8809 closed New feature (wontfix)
Better error message when can't import url callback
Reported by: | TP | Owned by: | nobody |
---|---|---|---|
Component: | Core (URLs) | Version: | dev |
Severity: | Normal | Keywords: | error message |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
in django.core.urlresolvers _get_callback it would be helpful to display not just the module name that couldn't be imported, but the entire urls.py line that was the problem. Without more information it's incredibly hard to track down WHICH urls.py file has the problem and which line in that file is problematic.
Attachments (3)
Change History (23)
comment:1 by , 16 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 14 years ago
comment:3 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
follow-up: 5 comment:4 by , 14 years ago
Has patch: | set |
---|---|
Needs tests: | set |
comment:5 by , 14 years ago
I have added a patch for this ticket. I tested it and it works fine, mentions the file and line number. Could someone please test it?
by , 14 years ago
Attachment: | fix_ticket_8809_urlsresolvers_error_message.diff added |
---|
Changed the import line to match PEP8 standards.
comment:6 by , 14 years ago
Patch needs improvement: | set |
---|
This patch makes a number of assumptions that are not reliable:
- That url patterns are always found in a file named "urls.py" (in fact they can be in any module, or even just an object with a get_urls() method).
- That the exact string in the RegexURLPattern._callback attribute can be found literally in the urls.py file (this will fail when the prefix argument to "patterns" is used; also, the view string could be constructed dynamically via string interpolation).
Also, the patch needs an automated test, integrated in Django's test suite.
I don't see any way that this approach (trying to reconstruct the information after the fact by literal searching in code files) will be workable. The information instead needs to be preserved from the initial definition in the urls.py if it's to be provided later in the error. The easiest way to do this would be to resolve the import immediately rather than lazily, but that's not acceptable as it could cause circular import issues in cases that currently work. The only alternatives I can see at the moment (having not looked into it deeply yet) would involve some rather nasty frame-object magic. This is not going to be a simple or easy fix.
comment:7 by , 14 years ago
That frame-object magic must happen at the moment of loading the patterns, since that information is lost when the url-files are read. The patterns
function will have to introspect which module is actually calling it and attach that information to the RexegURLPattern
before handing it off.
It sounds like a lot of ugly meta-work for a problem where just adding the original regex (which is available in the context) will help considerably without having to pinpoint it exactly.
by , 14 years ago
Attachment: | django8809-urlerror.diff added |
---|
comment:8 by , 14 years ago
Made a patch which adds the needed info in debug-mode because I am not a big supporter of adding this kind of meta-data in production. Need to think about how to create a test for it :-)
comment:9 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
by , 14 years ago
Attachment: | django8809-urlerror.2.diff added |
---|
comment:10 by , 14 years ago
Well, this one makes the information slightly more reliable. When a pattern is created without an url()-call, line-information is not reliable so it only shows the module. Included a set of tests.
comment:11 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
comment:14 by , 12 years ago
Component: | Core (Other) → Core (URLs) |
---|
comment:15 by , 12 years ago
Needs tests: | unset |
---|
Changed 'Needs Tests' to unset. Current patch has test cases.
comment:16 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:17 by , 11 years ago
In django.core.urlresolvers.py:
if not callable(lookup_view): mod_name, func_name = get_mod_func(lookup_view) if func_name == '': return lookup_view try: mod = import_module(mod_name) except ImportError: parentmod, submod = get_mod_func(mod_name) if (not can_fail and submod != '' and not module_has_submodule(import_module(parentmod), submod)): raise ViewDoesNotExist( "Could not import %s. Parent module %s does not exist." % (lookup_view, mod_name)) if not can_fail: raise else: try: lookup_view = getattr(mod, func_name) if not callable(lookup_view): raise ViewDoesNotExist( "Could not import %s.%s. View is not callable." % (mod_name, func_name)) except AttributeError: if not can_fail: raise ViewDoesNotExist( "Could not import %s. View does not exist in module %s." % (lookup_view, mod_name)) return lookup_view
This explains why I have closed this as fixed...
follow-up: 19 comment:18 by , 11 years ago
Resolution: | fixed |
---|---|
Status: | closed → new |
I'm not convinced that code addresses the request in this ticket. Can you at least check that the code is more recent than the latest discussions here?
comment:19 by , 11 years ago
Replying to aaugustin:
I'm not convinced that code addresses the request in this ticket. Can you at least check that the code is more recent than the latest discussions here?
The issue was to change the message such that we could know which line has problem(if there are several url files, it will be difficult.)
I think when we are specifying which particular view
does not exists in which module
, the user now knows what is missing and where, which wasn't there before. I think that very much solves this issue.
So I closed the ticket.
Am I wrong??
comment:20 by , 10 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Since using strings (rather than callables) in URL patterns is deprecated, I believe we can close this as "won't fix".
Hi,
I would like to implement this by searching through the urls.py or add a field where the RegexUrlPattern is created.
By the way, where in the source are the RegexUrlPattern objects created?