Skip to content

Commit

Permalink
Prevents crash when a route resolves to a 404 (#129)
Browse files Browse the repository at this point in the history
multiple issues:
 * resolve() might throw, handle that case
 * unhandled exception in `process_request` leads to last successful
   `request_model` remain in `DataCollector` and being used to create
   a response model for the current failed request, leading to
   a constraint violation thrown by the db (creating another response
   for the previously succesful request)

resolution
 * handle 404 by saving NULL/None as view name
 * clean out `DataCollector` state when starting a request, before doing
   anything.

Might help #26
  • Loading branch information
chrono authored and avelis committed Jul 13, 2016
1 parent cb0a4fd commit 4355083
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 19 deletions.
25 changes: 13 additions & 12 deletions silk/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,19 @@ def _apply_dynamic_mappings(self):

@silk_meta_profiler()
def process_request(self, request):
request_model = None
if _should_intercept(request):
Logger.debug('process_request')
request.silk_is_intercepted = True
self._apply_dynamic_mappings()
if not hasattr(SQLCompiler, '_execute_sql'):
SQLCompiler._execute_sql = SQLCompiler.execute_sql
SQLCompiler.execute_sql = execute_sql
request_model = RequestModelFactory(request).construct_request_model()
DataCollector().configure(request_model)
else:
DataCollector().clear()
DataCollector().clear()

if not _should_intercept(request):
return

Logger.debug('process_request')
request.silk_is_intercepted = True
self._apply_dynamic_mappings()
if not hasattr(SQLCompiler, '_execute_sql'):
SQLCompiler._execute_sql = SQLCompiler.execute_sql
SQLCompiler.execute_sql = execute_sql
request_model = RequestModelFactory(request).construct_request_model()
DataCollector().configure(request_model)

@transaction.atomic()
def _process_response(self, request, response):
Expand Down
24 changes: 17 additions & 7 deletions silk/model_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import base64
from uuid import UUID

from django.core.urlresolvers import resolve
from django.core.urlresolvers import resolve, Resolver404

from silk import models
from silk.collector import DataCollector
Expand Down Expand Up @@ -155,20 +155,30 @@ def query_params(self):
encoded_query_params = json.dumps(query_params_dict)
return encoded_query_params

def construct_request_model(self):
body, raw_body = self.body()
query_params = self.query_params()
path = self.request.path
resolved = resolve(path)
def view_name(self):
try:
resolved = resolve(self.request.path)
except Resolver404:
return None

try:
# view_name is set in Django >= 1.8
view_name = resolved.view_name
return resolved.view_name
except AttributeError:
# support for Django 1.6 and 1.7 in which no view_name is set
view_name = resolved.url_name
namespace = resolved.namespace
if namespace:
view_name = namespace + ':' + view_name

return view_name

def construct_request_model(self):
body, raw_body = self.body()
query_params = self.query_params()
path = self.request.path
view_name = self.view_name()

request_model = models.Request.objects.create(
path=path,
encoded_headers=self.encoded_headers(),
Expand Down

0 comments on commit 4355083

Please sign in to comment.