0

UPDATE: Added the code I was accessing that threw the error

For a CS50 project I'm working on with a wiki page, I'm trying to send the right custom 404 error when a user types a page that doesn't exist in wiki/TITLE however when I type a missing page, Django throws a 500 instead of a 404. Is this a common error or did I make my error message wrong? Debug is set to False and Allowed Hosts is configured to ['*'] in settings:

Here's my custom error handlers in views.py:

def error_404(request, exception):
    context = {}
    response = render(request, 'encyclopedia/error_404.html', context=context)
    response.status_code = 404
    return response


def error_500(request):
    context = {}
    response = render(request, 'encyclopedia/error_500.html', context=context)
    response.status_code = 500
    return response

Here's how they are in wiki/urls.py:

from django.contrib import admin
from django.urls import include, path
from django.conf.urls import handler404, handler500

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("encyclopedia.urls")),
]

handler404 = "encyclopedia.views.error_404"
handler500 = "encyclopedia.views.error_500"

here's the function in views.py that I'm accessing but going to wiki/C:

#function gets entry from index.html's <li>
def entry_page(request, entry):
    name = entry                     # Places the title       
    print(f"checking the title: {entry}")                            
    text = util.get_entry(entry)     # Grabs the entry using the util function
    html = md_converter(text)  

    if text is not None:
        return render(request, "encyclopedia/entry.html", {
            "title": name,
            "entry": html
        })

And here's my urls.py for good measure:

from django.urls import path

from . import views

app_name = "encyclopedia"
urlpatterns = [
    path("", views.index, name="index"),
    path("wiki/<str:entry>", views.entry_page, name="entry"),
    path("wiki/edit/<str:title>", views.edit, name="edit"),
    path("search", views.search, name="search"),
    path("random", views.random_page, name="random"),
    path("create_entry",views.create_entry, name="create_entry")
]

Here's what the terminal shows (my styles.css is throwing a 404 for some reason but I haven't changed anything there...that's a separate issue): my terminal when I go to a page that isn't there

Los
  • 147
  • 1
  • 11
  • 1
    set `DEBUG=True` and try to access the page. You will see whats wrong in `/wiki/C` – JPG Jul 03 '21 at 02:25
  • That page is just an example to trigger the error, DEBUG True shows a 404 just fine. I'm testing the 404 error functionality with DEBUG set to false – Los Jul 03 '21 at 02:26
  • Changing it to true and typing in a false url throws: "decoding to str: need a bytes-like object, NoneType found". Is that anything? – Los Jul 03 '21 at 02:28
  • Yeah, it is an exception/error and thus it should show 500 page, not 404 – JPG Jul 03 '21 at 02:29
  • 500 means your program messed up. Keep the debug mode on till you fixed the cause of the exception. You have not provided the part of the source code that causes the error, so we cannot help you further. When your code understands that the user is trying to access a non-existent page (from your error, likely using something like `if foo is None`), raise a `django.http.Http404`. – Amadan Jul 03 '21 at 02:42
  • Ah gotcha, I'll update the post with some of the code I'm accessing – Los Jul 03 '21 at 15:59

2 Answers2

1

There could be something wrong with your code. Django doc clearly says

The 404 view is also called if Django doesn’t find a match after checking every regular expression in the URLconf.

https://docs.djangoproject.com/en/3.2/ref/views/#error-views

kawadhiya21
  • 2,458
  • 21
  • 34
0

Figured it out. Thanks ya'll.

There was an error in the function I was using to grab the page. I wasn't checking to see if the URL was valid when looking up a particular wiki entry.

Changing entry_page in views.py to this made it work!:

def entry_page(request, entry):                              
if entry in util.list_entries():
    name = entry                     # Places the title    
    text = util.get_entry(entry)     # Grabs the entry using the util function
    html = md_converter(text)  
    return render(request, "encyclopedia/entry.html", {
        "title": name,
        "entry": html
    })
else:  
        return render(request, "encyclopedia/error_404.html" )

Glad it wasn't Django messing up, just me lol

Los
  • 147
  • 1
  • 11
  • `return render(req, template)` just paints the 404 page, but does not actually return the 404 status. If the client is looking at the status code, they would think everything is okay, since they receive 200 OK (with some text). Either make sure to return the correct status code using `return render(req, template, status=404)`, or, preferably, raise the `Http404` shortcut exception I showed above. Here's the [Django tutorial](https://docs.djangoproject.com/en/3.2/intro/tutorial03/#raising-a-404-error) showing you how to do it correctly. – Amadan Jul 06 '21 at 08:28
  • Ah, that makes even more sense. I'll edit the code to reflect that – Los Jul 06 '21 at 17:51