File: handlingerrors.rst

package info (click to toggle)
python-klein 24.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,012 kB
  • sloc: python: 6,371; makefile: 130
file content (98 lines) | stat: -rw-r--r-- 2,484 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
==========================
Example -- Handling Errors
==========================

It may be desirable to have uniform error-handling code for many routes.
We can do this with ``Klein.handle_errors``.

Below we have created a class that will translate ``NotFound`` exceptions into a custom 404 response.

.. code-block:: python

    from klein import Klein

    class NotFound(Exception):
        pass


    class ItemStore:
        app = Klein()

        @app.handle_errors(NotFound)
        def notfound(self, request, failure):
            request.setResponseCode(404)
            return 'Not found, I say'

        @app.route('/droid/<string:name>')
        def droid(self, request, name):
            if name in ['R2D2', 'C3P0']:
                raise NotFound()
            return 'Droid found'

        @app.route('/bounty/<string:target>')
        def bounty(self, request, target):
            if target == 'Han Solo':
                return '150,000'
            raise NotFound()


    if __name__ == '__main__':
        store = ItemStore()
        store.app.run('localhost', 8080)


The following cURL commands (and output) can be used to test this behaviour::

    curl -L http://localhost:8080/droid/R2D2
    Not found, I say

    curl -L http://localhost:8080/droid/Janeway
    Droid found

    curl -L http://localhost:8080/bounty/things
    Not found, I say


Example - Catch All Routes
==========================

A simple way to create a catch-all function, which serves every URL that doesn't match a route, is to use a ``path`` variable in the route.

.. code-block:: python

    from klein import Klein

    class OnlyOneRoute:
        app = Klein()

        @app.route('/api/<path:catchall>')
        def catchAll(self, request, catchall):
            request.redirect('/api')

        @app.route('/api')
        def home(self, request):
            return 'API Home'

        @app.route('/api/v1')
        def v1(self, request):
            return 'Version 1 - Home'


    if __name__ == '__main__':
        oneroute = OnlyOneRoute()
        oneroute.app.run('localhost', 8080)


Use cURL to verify that only ``/api`` and ``/api/v1`` return content, all other requests are redirected::

   curl -L http://localhost:8080/api
   API Home

   curl -L localhost:8080/api/v1
   Version 1 - Home

   curl -L localhost:8080/api/another
   API Home


This method can also be used on the root route, in which case it will catch every request which doesn't match a route.