How do I make an error handler with flask - flask

I am creating a web application and I would like to do a styled 404 page not found if someone tries to enter one of my routes that is not created. Is there a way I can do this?

welcome to stackoverflow!
To create a error handler of any error code in flask you must do the following, for my example I will use a 404 error as requested in the post:
#app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
If you want to error handle a 505 just substitut the 404 for a 505 and create a new html file in templates

Related

i am getting 405 error for get method in my django api, instead, i want a default message for get method

For django API, which we have written, post method is allowed but instead of get method, i am getting 405 error, but instead i want some default message like- "error". I am sharing my code. Please let me know if anyone can help.
#api_view(['GET'])
#permission_classes([AllowAny])
Error which i am getting in my script is :
"GET /hashtaggenerator HTTP/1.1" 405 40
and on postman i am getting:
{
"detail": "Method \"GET\" not allowed."
}

Livewire 404 error when refreshing component with parameter

When i try to refresh (from his child) a component directly displayed by a route like this :
Route::get('/facility/{idinstall}', Facility::class)->where(['idinstall' => '[0-9.]+' ]);
Or when i try to upload file like in the documentation i got a 404 error message like this :
/livewire/message/stock.facility 404 (Not Found)
Any idea ?

Misconfigured custom HTTP error templates in Django project (404,500)

I am in Django HTTP error codes hell. Would be great if an expert can help me out of my misconfiguration.
My Django project runs with nginx as a reverse proxy coupled to a gunicorn application server.
Requirement:
I want a custom Page not found template to render (i.e. 404) when a url pattern is entered that doesn't exist in my urls.py. Sounds simple enough, and is well documented.
I have already gone ahead and implemented this.
The Problem:
Assume example.com is my live project.
1) If I try to access https://example.com/asdfasdf (i.e. unmatched, random gibberish) on my production server, it displays the 500 template instead of 404.
2) Next, if I try to curl the said url pattern via curl -I https://example.com/asdfasdf/, I see 200 OK instead of 404 or 500. Wth?
3) Moreover, if I try the same behavior with Debug = True on localhost, 404 is returned correctly (both template and HTTP error code are in consonance).
These 3 behaviors are quite perplexing.
My configuration:
I created error_views.py and inserted it in the folder where I keep my regular views.py. This error file contains:
from django.shortcuts import render
def server_error(request):
return render(request, '500.html')
def not_found(request):
return render(request, '404.html')
def permission_denied(request):
return render(request, '404.html')
def bad_request(request):
return render(request, '404.html')
In my urls.py (kept in the same folder as settings.py), I added the following after all url patterns:
handler404 = 'my_app.error_views.not_found'
handler500 = 'my_app.error_views.server_error'
handler403 = 'my_app.error_views.permission_denied'
handler400 = 'my_app.error_views.bad_request'
I created 404.html and 500.html, and inserted them in the default /templates/ directory.
In settings.py, I have ALLOWED_HOSTS = ['*']
Lastly, my nginx conf dealing with this is as follows (placed within the server block in the virtual host file):
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/ubuntu/this_proj/project_dir/templates/;
}
location = /too_bad.svg {
root /home/ubuntu/this_proj/project_dir/static/img/;
}
All of this is fairly regular stuff and I'm missing what I've misconfigured here. Can an expert guide me out of this mess?
Thanks in advance, and please ask for more information in case warranted.
Note: I tried solutions provided in similar questions on SO here and here. Needless to say, those misconfigurations were very different, displaying none of the symptoms I'm seeing.
If you use a custom handler, you have to explicitly set the proper http status for the response object. If you don't set the status, the default is 200 OK.
def not_found(request):
return render(request, '404.html', status=404)

Django test always returning 301

I know there are few same posts with this problem, but they doesn't helped for me. I'm always got a 301 status in tests:
self.client.get('/')
and this:
self.client.get('/admin/')
return:
AssertionError: 301 != 200
All urls will returning 301 status... Only way that help is: self.client.get('/', follow=True)
Anybody knows where is problem?
301 is status for redirection, whitch means your get request first have response that is the 301.
Http headers contains the url to redirect to...
If you want your request to follow, you have pass in follow=True, which indicates the method to automatically trigger another request to the redirect url.
There can be many redirections.
It's a common error in assertion tests.
Open your browser to see if the tailing backslash has caused this issue.
I had the same error as you described.
My django code is:
response = self.client.get('**/admin**')<br>
self.assertEqual(response.status_code, 200)<br>
AssertionError: 301 != 200
This is my solution:
Option 1
self.client.get('**/admin/**')<br>
Option 2
self.client.get('**/admin**', follow=True)
Is the root URL protected by login? That's certainly the case for the admin URL, so it will redirect to the login page unless you have already logged in. If you have protected the root view with #login_required that would explain what you see.
This is how I solved it:
def test_index_status_code(self):
response = self.client.get('/backstage')
self.assertRedirects(response, '/backstage/', status_code=301, target_status_code=200)

Redirection + 403 error

I am searching for a way to have something like that :
return HttpResponseForbiddenRedirect(reverse("view_name"))
an HttpResponse which redirect to a view (with its name) but still throw a 403 error
I tried to do something like that :
class HttpResponseForbiddenRedirect(HttpResponse):
def __init__(self, redirect_to):
super(HttpResponseForbiddenRedirect, self).__init__()
self['Location'] = iri_to_uri(redirect_to)
self.status_code = 403
But it didn't work. For some reason I don't understand, I don't get any content
It doesn't work because you can't have a 403 response that is also acted upon as if it is a 302 response.
The HTTP spec tells browsers how to handle certain status codes, and so a browser getting a 403 won't bother to look to see if there's a Location header in the way that it would do with a 302.
If you want to redirect someone from X to Y because they're not allowed to see X, then just issue a standard 302, and do something like setting a message (using django.contrib.messages) to inform the user of why they've been redirected, or redirect them to a page that explains what is going on.
You're missing the idea behind HTTP status codes. Redirect is being made with HTTP code 301/302. So you cannot make redirect and return 403 at the same time. It is simply not a redirect, if there is no 301/302 code returned.
I don't get it why you need this, but you can always make a view like:
def my403view(request): # e.g. /403.html
return HttpResponseForbidden()
and to do your redirect with:
return HttpResponseRedirect(reverse("403.html"))
This will redirect(with code 302) to "my403view", and it will return 403.
I found a solution to this :
from app_name.views import my_view
....
retour = my_views(request)
return HttpResponseForbidden(retour)
It is in fact quite simple
And so I get the 403 error + the page I wanna load