From 6f79dd475dfaf9882d86fc2ac0b835b81d47960a Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Thu, 10 May 2018 17:31:49 +0200
Subject: [PATCH] Now return proper error payload on subsonic API

---
 api/funkwhale_api/subsonic/renderers.py |  6 ++++
 api/funkwhale_api/subsonic/views.py     | 39 +++++++++++++++----------
 2 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/api/funkwhale_api/subsonic/renderers.py b/api/funkwhale_api/subsonic/renderers.py
index 74cf13d8..3a566450 100644
--- a/api/funkwhale_api/subsonic/renderers.py
+++ b/api/funkwhale_api/subsonic/renderers.py
@@ -15,6 +15,9 @@ class SubsonicJSONRenderer(renderers.JSONRenderer):
             }
         }
         final['subsonic-response'].update(data)
+        if 'error' in final:
+            # an error was returned
+            final['subsonic-response']['status'] = 'failed'
         return super().render(final, accepted_media_type, renderer_context)
 
 
@@ -31,6 +34,9 @@ class SubsonicXMLRenderer(renderers.JSONRenderer):
             'version': '1.16.0',
         }
         final.update(data)
+        if 'error' in final:
+            # an error was returned
+            final['status'] = 'failed'
         tree = dict_to_xml_tree('subsonic-response', final)
         return b'<?xml version="1.0" encoding="UTF-8"?>\n' + ET.tostring(tree, encoding='utf-8')
 
diff --git a/api/funkwhale_api/subsonic/views.py b/api/funkwhale_api/subsonic/views.py
index 475e61aa..2692a3dd 100644
--- a/api/funkwhale_api/subsonic/views.py
+++ b/api/funkwhale_api/subsonic/views.py
@@ -31,15 +31,19 @@ def find_object(queryset, model_field='pk', field='id', cast=int):
                 raw_value = data[field]
             except KeyError:
                 return response.Response({
-                    'code': 10,
-                    'message': "required parameter '{}' not present".format(field)
+                    'error': {
+                        'code': 10,
+                        'message': "required parameter '{}' not present".format(field)
+                    }
                 })
             try:
                 value = cast(raw_value)
             except (TypeError, ValidationError):
                 return response.Response({
-                    'code': 0,
-                    'message': 'For input string "{}"'.format(raw_value)
+                    'error': {
+                        'code': 0,
+                        'message': 'For input string "{}"'.format(raw_value)
+                    }
                 })
             qs = queryset
             if hasattr(qs, '__call__'):
@@ -48,9 +52,11 @@ def find_object(queryset, model_field='pk', field='id', cast=int):
                 obj = qs.get(**{model_field: value})
             except qs.model.DoesNotExist:
                 return response.Response({
-                    'code': 70,
-                    'message': '{} not found'.format(
-                        qs.model.__class__.__name__)
+                    'error': {
+                        'code': 70,
+                        'message': '{} not found'.format(
+                            qs.model.__class__.__name__)
+                    }
                 })
             kwargs['obj'] = obj
             return func(self, request, *args, **kwargs)
@@ -83,15 +89,14 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         payload = {
             'status': 'failed'
         }
-        try:
+        if exc.__class__ in mapping:
             code, message = mapping[exc.__class__]
-        except KeyError:
-            return super().handle_exception(exc)
         else:
-            payload['error'] = {
-                'code': code,
-                'message': message
-            }
+            return super().handle_exception(exc)
+        payload['error'] = {
+            'code': code,
+            'message': message
+        }
 
         return response.Response(payload, status=200)
 
@@ -450,8 +455,10 @@ class SubsonicViewSet(viewsets.GenericViewSet):
         name = data.get('name', '')
         if not name:
             return response.Response({
-                'code': 10,
-                'message': 'Playlist ID or name must be specified.'
+                'error': {
+                    'code': 10,
+                    'message': 'Playlist ID or name must be specified.'
+                }
             }, data)
 
         playlist = request.user.playlists.create(
-- 
GitLab