@@ -33,6 +33,8 @@ the post:
3333* [ pyrollbar] ( https://rollbar.com/docs/notifier/pyrollbar/ ) monitoring
3434 instrumentation library,
3535 [ version 0.13.12] ( https://github.com/rollbar/pyrollbar/tree/v0.13.12 )
36+ * [ blinker] ( https://pypi.python.org/pypi/blinker ) for signaling support
37+ in Flask applications so pyrollbar can report on all errors
3638* A [ free Rollbar account] ( https://rollbar.com/ ) where we will send error
3739 data and view it when it is captured
3840* [ pip] ( https://pip.pypa.io/en/stable/ ) and the
@@ -43,7 +45,7 @@ the post:
4345If you need help getting your
4446[ development environment] ( /development-environments.html ) configured
4547before running this code, take a look at
46- [ this guide for setting up Python 3 and Flask on Ubuntu 16.04 LTS] ( /blog/python-3-flask-green-unicorn-ubuntu-1604-xenial-xerus.html )
48+ [ this guide for setting up Python 3 and Flask on Ubuntu 16.04 LTS] ( /blog/python-3-flask-green-unicorn-ubuntu-1604-xenial-xerus.html ) .
4749
4850All code in this blog post is available open source under the MIT license
4951on GitHub under the
@@ -73,22 +75,24 @@ The command prompt will change after activating the virtualenv:
7375Remember that you need to activate the virtualenv in every new terminal
7476window where you want to use the virtualenv to run the project.
7577
76- Flask and Rollbar can now be installed into the now-activated virtualenv.
78+ Flask, Rollbar and Blinker can now be installed into the now-activated
79+ virtualenv.
7780
7881```
79- pip install flask==0.12.2 rollbar==0.13.12
82+ pip install flask==0.12.2 rollbar==0.13.12 blinker==1.4
8083```
8184
8285Our required dependencies should be installed within our virtualenv
8386after a short installation period. Look for output like the following to
8487confirm everything worked.
8588
8689```
87- Installing collected packages: MarkupSafe, Jinja2, itsdangerous, click, Werkzeug, flask , idna, urllib3, chardet, certifi, requests, six, rollbar
88- Running setup.py install for MarkupSafe ... done
90+ Installing collected packages: blinker, itsdangerous, click, MarkupSafe, Jinja2, Werkzeug, Flask , idna, urllib3, chardet, certifi, requests, six, rollbar
91+ Running setup.py install for blinker ... done
8992 Running setup.py install for itsdangerous ... done
93+ Running setup.py install for MarkupSafe ... done
9094 Running setup.py install for rollbar ... done
91- Successfully installed Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 certifi-2017.4.17 chardet-3.0.4 click-6.7 flask-0.12.2 idna-2.5 itsdangerous-0.24 requests-2.18.1 rollbar-0.13.12 six-1.10.0 urllib3-1.21.1
95+ Successfully installed Flask-0.12.2 Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 blinker-1.4 certifi-2017.4.17 chardet-3.0.4 click-6.7 idna-2.5 itsdangerous-0.24 requests-2.18.1 rollbar-0.13.12 six-1.10.0 urllib3-1.21.1
9296```
9397
9498Now that we have our Python dependencies installed into our virtualenv
@@ -102,24 +106,26 @@ code.
102106
103107``` python
104108import re
105- from flask import Flask, render_template
109+ from flask import Flask, render_template, Response
106110from werkzeug.exceptions import NotFound
107111
108112
109113app = Flask(__name__ )
110-
111114MIN_PAGE_NAME_LENGTH = 2
112115
113116
114117@app.route (" /<string:page>/" )
115118def show_page (page ):
116- valid_length = len (page) >= MIN_PAGE_NAME_LENGTH
117- valid_name = re.match(' ^[a-z]+$' , page.lower()) is not None
118- if valid_length and valid_name:
119- return render_template(" {} .html" .format(page))
120- else :
121- msg = " Sorry, couldn't find page with name {} " .format(page)
122- raise NotFound(msg)
119+ try :
120+ valid_length = len (page) >= MIN_PAGE_NAME_LENGTH
121+ valid_name = re.match(' ^[a-z]+$' , page.lower()) is not None
122+ if valid_length and valid_name:
123+ return render_template(" {} .html" .format(page))
124+ else :
125+ msg = " Sorry, couldn't find page with name {} " .format(page)
126+ raise NotFound(msg)
127+ except :
128+ return Response(" 404 Not Found" )
123129
124130
125131if __name__ == " __main__" :
@@ -235,26 +241,32 @@ lines.
235241~~ import os
236242import re
237243~~ import rollbar
238- from flask import Flask, render_template
244+ from flask import Flask, render_template, Response
239245from werkzeug.exceptions import NotFound
240246
241247
242248app = Flask(__name__ )
243- ~~ rollbar.init(os.environ.get(' ROLLBAR_SECRET' ))
244- ~~ rollbar.report_message(' Rollbar is configured correctly' )
245-
246249MIN_PAGE_NAME_LENGTH = 2
247250
248251
252+ ~~ @ app.before_first_request
253+ ~~ def add_monitoring ():
254+ ~~ rollbar.init(os.environ.get(' ROLLBAR_SECRET' ))
255+ ~~ rollbar.report_message(' Rollbar is configured correctly' )
256+
257+
249258@app.route (" /<string:page>/" )
250259def show_page (page ):
251- valid_length = len (page) >= MIN_PAGE_NAME_LENGTH
252- valid_name = re.match(' ^[a-z]+$' , page.lower()) is not None
253- if valid_length and valid_name:
254- return render_template(" {} .html" .format(page))
255- else :
256- msg = " Sorry, couldn't find page with name {} " .format(page)
257- raise NotFound(msg)
260+ try :
261+ valid_length = len (page) >= MIN_PAGE_NAME_LENGTH
262+ valid_name = re.match(' ^[a-z]+$' , page.lower()) is not None
263+ if valid_length and valid_name:
264+ return render_template(" {} .html" .format(page))
265+ else :
266+ msg = " Sorry, couldn't find page with name {} " .format(page)
267+ raise NotFound(msg)
268+ except :
269+ return Response(" 404 Not Found" )
258270
259271
260272if __name__ == " __main__" :
@@ -305,9 +317,66 @@ all the errors from our application, not a test event.
305317
306318
307319## Testing Error Handling
320+ How do we make sure real errors are reported rather than just a simple
321+ test event? We just need to add a few more lines of code to our app.
322+
323+ ``` python
324+ import os
325+ import re
326+ import rollbar
327+ ~~ import rollbar.contrib.flask
328+ from flask import Flask, render_template, Response
329+ ~~ from flask import got_request_exception
330+ from werkzeug.exceptions import NotFound
331+
332+
333+ app = Flask(__name__ )
334+ MIN_PAGE_NAME_LENGTH = 2
335+
336+
337+ @app.before_first_request
338+ def add_monitoring ():
339+ rollbar.init(os.environ.get(' ROLLBAR_SECRET' ))
340+ ~~ # # delete the next line if you dont want this event anymore
341+ rollbar.report_message(' Rollbar is configured correctly' )
342+ ~~ got_request_exception.connect(rollbar.contrib.flask.report_exception, app)
343+
344+
345+ @app.route (" /<string:page>/" )
346+ def show_page (page ):
347+ try :
348+ valid_length = len (page) >= MIN_PAGE_NAME_LENGTH
349+ valid_name = re.match(' ^[a-z]+$' , page.lower()) is not None
350+ if valid_length and valid_name:
351+ return render_template(" {} .html" .format(page))
352+ else :
353+ msg = " Sorry, couldn't find page with name {} " .format(page)
354+ raise NotFound(msg)
355+ except :
356+ ~~ rollbar.report_exc_info()
357+ return Response(" 404 Not Found" )
358+
359+
360+ if __name__ == " __main__" :
361+ app.run(debug = True )
362+ ```
363+
364+ The above highlighted code modifies the application so it reports all Flask
365+ errors as well as our HTTP 404 not found issues that happen within the
366+ ` show_page ` function.
367+
368+ Make sure your Flask development server is running and try to go to
369+ [ localhost:5000/b/] ( http://localhost:5000/b/ ) . You will receive an HTTP
370+ 404 exception and it will be reported to Rollbar. Next go to
371+ [ localhost:5000/fullstackpython/] ( http://localhost:5000/fullstackpython/ ) and
372+ an HTTP 500 error will occur.
373+
374+ You should see an aggregation of errors as you test out these errors:
308375
376+ <img src =" /img/170723-monitor-flask-apps/error-aggregation.jpg " width =" 100% " class =" technical-diagram img-rounded " style =" border :1px solid #ccc " alt =" Rollbar dashboard showing aggregations of errors. " >
309377
310- (links to Python docs)
378+ Woohoo, we finally have our Flask app reporting all errors that occur
379+ for any user back to the hosted Rollbar monitoring service!
311380
312381
313382## What's Next?
0 commit comments