1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

vweb: add an overridable .not_found() method, for making a custom 404 page + tests fixes (#17936)

This commit is contained in:
Casper Kuethe 2023-04-11 23:50:03 +02:00 committed by GitHub
parent f9c186a400
commit 838083e610
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 16 deletions

View File

@ -378,6 +378,19 @@ pub fn (mut app App) with_auth() bool {
} }
``` ```
### Fallback route
You can implement a fallback `not_found` route that is called when a request is made and no
matching route is found.
**Example:**
``` v ignore
pub fn (mut app App) not_found() vweb.Result {
app.set_status(404, 'Not Found')
return app.html('<h1>Page not found</h1>')
}
```
### Controllers ### Controllers
Controllers can be used to split up app logic so you are able to have one struct Controllers can be used to split up app logic so you are able to have one struct
per `"/"`. E.g. a struct `Admin` for urls starting with `"/admin"` and a struct `Foo` per `"/"`. E.g. a struct `Admin` for urls starting with `"/admin"` and a struct `Foo`

View File

@ -14,7 +14,7 @@ struct Admin {
} }
['/admin/duplicate'] ['/admin/duplicate']
fn (mut app App) duplicate() vweb.Result { pub fn (mut app App) duplicate() vweb.Result {
return app.text('duplicate') return app.text('duplicate')
} }

View File

@ -1,9 +1,6 @@
import os import os
import time import time
import json
import net
import net.http import net.http
import io
const ( const (
sport = 12382 sport = 12382
@ -91,6 +88,21 @@ fn test_other_path() {
assert x.body == 'Other path' assert x.body == 'Other path'
} }
fn test_different_404() {
res_app := http.get('http://${localserver}/zxcnbnm') or { panic(err) }
assert res_app.status() == .not_found
assert res_app.body == '404 From App'
res_admin := http.get('http://${localserver}/admin/JHKAJA') or { panic(err) }
assert res_admin.status() == .not_found
assert res_admin.body == '404 From Admin'
// Other doesn't have a custom 404 so the vweb.Context's not_found is expected
res_other := http.get('http://${localserver}/other/unknown') or { panic(err) }
assert res_other.status() == .not_found
assert res_other.body == '404 Not Found'
}
fn test_shutdown() { fn test_shutdown() {
// This test is guaranteed to be called last. // This test is guaranteed to be called last.
// It sends a request to the server to shutdown. // It sends a request to the server to shutdown.

View File

@ -46,32 +46,42 @@ fn main() {
} }
['/'] ['/']
fn (mut app App) home() vweb.Result { pub fn (mut app App) home() vweb.Result {
return app.text('App') return app.text('App')
} }
['/path'] ['/path']
fn (mut app App) app_path() vweb.Result { pub fn (mut app App) app_path() vweb.Result {
return app.text('App path') return app.text('App path')
} }
pub fn (mut app App) not_found() vweb.Result {
app.set_status(404, 'Not Found')
return app.text('404 From App')
}
['/'] ['/']
fn (mut app Admin) admin_home() vweb.Result { pub fn (mut app Admin) admin_home() vweb.Result {
return app.text('Admin') return app.text('Admin')
} }
['/path'] ['/path']
fn (mut app Admin) admin_path() vweb.Result { pub fn (mut app Admin) admin_path() vweb.Result {
return app.text('Admin path') return app.text('Admin path')
} }
pub fn (mut app Admin) not_found() vweb.Result {
app.set_status(404, 'Not Found')
return app.text('404 From Admin')
}
['/'] ['/']
fn (mut app Other) other_home() vweb.Result { pub fn (mut app Other) other_home() vweb.Result {
return app.text('Other') return app.text('Other')
} }
['/path'] ['/path']
fn (mut app Other) other_path() vweb.Result { pub fn (mut app Other) other_path() vweb.Result {
return app.text('Other path') return app.text('Other path')
} }

View File

@ -124,14 +124,16 @@ fn test_http_client_index() {
} }
fn test_http_client_404() { fn test_http_client_404() {
server := 'http://${localserver}'
url_404_list := [ url_404_list := [
'http://${localserver}/zxcnbnm', '/zxcnbnm',
'http://${localserver}/JHKAJA', '/JHKAJA',
'http://${localserver}/unknown', '/unknown',
] ]
for url in url_404_list { for url in url_404_list {
res := http.get(url) or { panic(err) } res := http.get('${server}${url}') or { panic(err) }
assert res.status() == .not_found assert res.status() == .not_found
assert res.body == '404 on "${url}"'
} }
} }
@ -234,7 +236,6 @@ fn test_http_client_shutdown_does_not_work_without_a_cookie() {
return return
} }
assert x.status() == .not_found assert x.status() == .not_found
assert x.body == '404 Not Found'
} }
fn testsuite_end() { fn testsuite_end() {

View File

@ -103,6 +103,12 @@ pub fn (mut app App) json() vweb.Result {
return app.ok(app.req.data) return app.ok(app.req.data)
} }
// Custom 404 page
pub fn (mut app App) not_found() vweb.Result {
app.set_status(404, 'Not Found')
return app.html('404 on "${app.req.url}"')
}
pub fn (mut app App) shutdown() vweb.Result { pub fn (mut app App) shutdown() vweb.Result {
session_key := app.get_cookie('skey') or { return app.not_found() } session_key := app.get_cookie('skey') or { return app.not_found() }
if session_key != 'superman' { if session_key != 'superman' {

View File

@ -740,7 +740,7 @@ fn handle_route[T](mut app T, url urllib.URL, routes &map[string]Route, tid int)
} }
} }
// Route not found // Route not found
app.conn.write(vweb.http_404.bytes()) or {} app.not_found()
} }
// validate_middleware validates and fires all middlewares that are defined in the global app instance // validate_middleware validates and fires all middlewares that are defined in the global app instance