Skip to content
This repository
Browse code

Error handler vows. 100% covered now

  • Loading branch information...
commit 44c432d26ab919a618f6973f54f5b5b50b520c75 1 parent e61c8e1
Bernardo Heynemann authored March 28, 2013
8  thumbor/error_handlers/sentry.py
@@ -15,7 +15,7 @@
15 15
 
16 16
 
17 17
 class ErrorHandler(object):
18  
-    def __init__(self, config):
  18
+    def __init__(self, config, client=None):
19 19
         import raven
20 20
 
21 21
         dsn = config.SENTRY_DSN_URL
@@ -25,7 +25,7 @@ def __init__(self, config):
25 25
                 "then you must specify the Sentry DSN using the SENTRY_DSN_URL configuration."
26 26
             )
27 27
 
28  
-        self.sentry = raven.Client(dsn)
  28
+        self.sentry = client or raven.Client(dsn)
29 29
         self.modules = self.get_modules()
30 30
 
31 31
     def get_modules(self):
@@ -54,7 +54,9 @@ def handle_error(self, context, handler, exception):
54 54
 
55 55
         cookies = {}
56 56
         for cookie in extra['Headers']['Cookie'].split(';'):
57  
-            values = cookie.split('=')
  57
+            if not cookie:
  58
+                continue
  59
+            values = cookie.strip().split('=')
58 60
             key, val = values[0], "".join(values[1:])
59 61
             cookies[key] = val
60 62
         extra['Headers']['Cookie'] = cookies
111  vows/sentry_error_handler_vows.py
... ...
@@ -0,0 +1,111 @@
  1
+#!/usr/bin/python
  2
+# -*- coding: utf-8 -*-
  3
+
  4
+# thumbor imaging service
  5
+# https://github.com/globocom/thumbor/wiki
  6
+
  7
+# Licensed under the MIT license:
  8
+# http://www.opensource.org/licenses/mit-license
  9
+# Copyright (c) 2011 globo.com timehome@corp.globo.com
  10
+
  11
+from pyvows import Vows, expect
  12
+
  13
+from thumbor import __version__
  14
+from thumbor.error_handlers.sentry import ErrorHandler
  15
+from thumbor.config import Config
  16
+from thumbor.context import Context, ServerParameters
  17
+
  18
+
  19
+class FakeSentry(object):
  20
+    def __init__(self, dsn):
  21
+        self.captured_exceptions = []
  22
+
  23
+    def captureException(self, exception, *args, **kw):
  24
+        self.captured_exceptions.append((exception, args, kw))
  25
+
  26
+
  27
+class FakeRequest(object):
  28
+    def __init__(self):
  29
+        self.headers = {
  30
+            'header1': 'value1',
  31
+            'Cookie': 'cookie1=value; cookie2=value2;'
  32
+        }
  33
+
  34
+        self.url = "test/"
  35
+        self.method = "GET"
  36
+        self.arguments = []
  37
+        self.body = "body"
  38
+        self.query = "a=1&b=2"
  39
+        self.remote_ip = "127.0.0.1"
  40
+
  41
+    def full_url(self):
  42
+        return "http://test/%s" % self.url
  43
+
  44
+
  45
+class FakeHandler(object):
  46
+    def __init__(self):
  47
+        self.request = FakeRequest()
  48
+
  49
+
  50
+@Vows.batch
  51
+class SentrErrorHandlerVows(Vows.Context):
  52
+    class WhenInvalidConfiguration(Vows.Context):
  53
+        def topic(self):
  54
+            cfg = Config()
  55
+            ErrorHandler(cfg)
  56
+
  57
+        def should_be_error(self, topic):
  58
+            expect(topic).to_be_an_error()
  59
+            expect(topic).to_be_an_error_like(RuntimeError)
  60
+
  61
+    class WhenErrorOccurs(Vows.Context):
  62
+        def topic(self):
  63
+            cfg = Config(SECURITY_KEY='ACME-SEC', SENTRY_DSN_URL="http://sentry-dsn-url")
  64
+            server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None)
  65
+            server.security_key = 'ACME-SEC'
  66
+            ctx = Context(server, cfg, None)
  67
+
  68
+            client_mock = FakeSentry("FAKE DSN")
  69
+            handler = ErrorHandler(cfg, client=client_mock)
  70
+            http_handler = FakeHandler()
  71
+
  72
+            handler.handle_error(ctx, http_handler, RuntimeError("Test"))
  73
+
  74
+            return client_mock
  75
+
  76
+        def should_have_called_client(self, topic):
  77
+            expect(topic.captured_exceptions).not_to_be_empty()
  78
+            expect(topic.captured_exceptions).to_length(1)
  79
+
  80
+            exception, args, kw = topic.captured_exceptions[0]
  81
+            expect(exception.__class__.__name__).to_equal("RuntimeError")
  82
+            expect(kw).to_include('data')
  83
+            expect(kw).to_include('extra')
  84
+
  85
+            data, extra = kw['data'], kw['extra']
  86
+
  87
+            expect(extra).to_include('thumbor-version')
  88
+            expect(extra['thumbor-version']).to_equal(__version__)
  89
+
  90
+            expect(extra).to_include('Headers')
  91
+            expect(extra['Headers']).to_length(2)
  92
+
  93
+            expect(extra['Headers']).to_include('Cookie')
  94
+            expect(extra['Headers']['Cookie']).to_length(2)
  95
+
  96
+            expect(data['modules']).not_to_be_empty()
  97
+
  98
+            del data['modules']
  99
+
  100
+            expect(data).to_be_like({
  101
+                'sentry.interfaces.Http': {
  102
+                    'url': "http://test/test/",
  103
+                    'method': "GET",
  104
+                    'data': [],
  105
+                    'body': "body",
  106
+                    'query_string': "a=1&b=2"
  107
+                },
  108
+                'sentry.interfaces.User': {
  109
+                    'ip': "127.0.0.1",
  110
+                }
  111
+            })

0 notes on commit 44c432d

Please sign in to comment.
Something went wrong with that request. Please try again.