Repository: fossasia/open-event-server

Issue:
HTTP 500 on discount code not found
**Describe the bug**
When a `GET, `PATCH` and `DELETE` request is sent for a discount code that does not exist, a 500 error is raised instead of 404.

**To Reproduce**
Steps to reproduce the behavior:
Send a `GET`, `PATCH` or `DELETE` request for a discount code that does not exist, like, `/v1/discount-codes/<non-existent-id>`

**Expected behavior**
A 404 error should be returned instead of 500.

**Stacktrace**
```
INFO:werkzeug:127.0.0.1 - - [04/Jul/2018 19:09:54] "GET /v1/discount-codes/100 HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/binaryboy/Desktop/open-event-server/app/__init__.py", line 66, in __call__
    return self.app(environ, start_response)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/binaryboy/Desktop/open-event-server/app/api/helpers/permissions.py", line 45, in decorator
    return fn(*args, **kwargs)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/src/flask-rest-jsonapi/flask_rest_jsonapi/decorators.py", line 32, in wrapper
    return func(*args, **kwargs)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/views.py", line 88, in view
    return self.dispatch_request(*args, **kwargs)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/src/flask-rest-jsonapi/flask_rest_jsonapi/resource.py", line 67, in dispatch_request
    response = method(*args, **kwargs)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/src/flask-rest-jsonapi/flask_rest_jsonapi/decorators.py", line 56, in wrapper
    return func(*args, **kwargs)
  File "/Users/binaryboy/Desktop/open-event-server/.venv/src/flask-rest-jsonapi/flask_rest_jsonapi/resource.py", line 228, in get
    self.before_get(args, kwargs)
  File "/Users/binaryboy/Desktop/open-event-server/app/api/discount_codes.py", line 140, in before_get
    discount = db.session.query(DiscountCode).filter_by(id=kwargs.get('id')).one()
  File "/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2820, in one
    raise orm_exc.NoResultFound("No row was found for one()")
sqlalchemy.orm.exc.NoResultFound: No row was found for one()
/Users/binaryboy/Desktop/open-event-server/.venv/lib/python3.6/site-packages/flask/sessions.py:208: UserWarning: "localhost" is not a valid cookie domain, it must contain a ".". Add an entry to your hosts file, for example "localhost.localdomain", and use that instead.
  ' "{rv}.localdomain", and use that instead.'.format(rv=rv)
127.0.0.1 - - [04/Jul/2018 19:10:45] "PATCH /v1/discount-codes/100 HTTP/1.1" 422 -
INFO:werkzeug:127.0.0.1 - - [04/Jul/2018 19:10:45] "PATCH /v1/discount-codes/100 HTTP/1.1" 422 -
127.0.0.1 - - [04/Jul/2018 19:11:24] "PATCH /v1/discount-codes/100 HTTP/1.1" 422 -
INFO:werkzeug:127.0.0.1 - - [04/Jul/2018 19:11:24] "PATCH /v1/discount-codes/100 HTTP/1.1" 422 -
```
Will submit a PR to fix this.


Discussion:

Resolving patch:
diff --git a/app/api/discount_codes.py b/app/api/discount_codes.py
--- a/app/api/discount_codes.py
+++ b/app/api/discount_codes.py
@@ -137,9 +137,12 @@ def before_get(self, args, kwargs):
             return
 
         if kwargs.get('id'):
-            discount = db.session.query(DiscountCode).filter_by(id=kwargs.get('id')).one()
-            if not discount:
-                raise ObjectNotFound({'parameter': '{id}'}, "DiscountCode:  not found")
+            try:
+                discount = db.session.query(
+                    DiscountCode).filter_by(id=kwargs.get('id')).one()
+            except NoResultFound:
+                raise ObjectNotFound(
+                    {'parameter': '{id}'}, "DiscountCode:  not found")
 
             if discount.used_for == 'ticket' and has_access('is_coorganizer', event_id=discount.event_id):
                 self.schema = DiscountCodeSchemaTicket
@@ -180,9 +183,12 @@ def before_get_object(self, view_kwargs):
                 view_kwargs['id'] = None
 
         if view_kwargs.get('id'):
-            discount = self.session.query(DiscountCode).filter_by(id=view_kwargs.get('id')).one()
-            if not discount:
-                raise ObjectNotFound({'parameter': '{id}'}, "DiscountCode:  not found")
+            try:
+                discount = self.session.query(
+                    DiscountCode).filter_by(id=view_kwargs.get('id')).one()
+            except NoResultFound:
+                raise ObjectNotFound(
+                    {'parameter': '{id}'}, "DiscountCode: not found")
 
             if discount.used_for == 'ticket' and has_access('is_coorganizer', event_id=discount.event_id):
                 self.schema = DiscountCodeSchemaTicket
@@ -257,9 +263,12 @@ def before_get(self, args, kwargs):
         :param kwargs:
         :return:
         """
-        discount = db.session.query(DiscountCode).filter_by(id=kwargs.get('id')).one()
-        if not discount:
-            raise ObjectNotFound({'parameter': '{id}'}, "DiscountCode:  not found")
+        try:
+            discount = db.session.query(
+                DiscountCode).filter_by(id=kwargs.get('id')).one()
+        except NoResultFound:
+            raise ObjectNotFound(
+                {'parameter': '{id}'}, "DiscountCode: not found")
         if discount.used_for == 'ticket' and has_access('is_coorganizer', event_id=discount.event_id):
             self.schema = DiscountCodeSchemaTicket
 
@@ -288,9 +297,12 @@ def before_get(self, args, kwargs):
         :param kwargs:
         :return:
         """
-        discount = db.session.query(DiscountCode).filter_by(id=kwargs.get('id')).one()
-        if not discount:
-            raise ObjectNotFound({'parameter': '{id}'}, "DiscountCode:  not found")
+        try:
+            discount = db.session.query(
+                DiscountCode).filter_by(id=kwargs.get('id')).one()
+        except NoResultFound:
+            raise ObjectNotFound(
+                {'parameter': '{id}'}, "DiscountCode: not found")
 
         if discount.used_for == 'ticket' and has_access('is_coorganizer', event_id=discount.event_id):
             self.schema = DiscountCodeSchemaTicket


Test patch: