Throw more user-friendly exception inside the router in case invalid
type is passed to the API endpoint as an input.
@@ -387,7 +387,7 @@ class Router(object):
if 'x-api-model' in schema:
Model = op_resolver(schema['x-api-model'])
- instance = Model(**data)
+ instance = self._get_model_instance(model_cls=Model, data=data)
# Call validate on the API model - note we should eventually move all
# those model schema definitions into openapi.yaml
@@ -400,7 +400,7 @@ class Router(object):
LOG.debug('Missing x-api-model definition for %s, using generic Body '
'model.' % (endpoint['operationId']))
model = Body
- instance = model(**data)
+ instance = self._get_model_instance(model_cls=model, data=data)
kw[argument_name] = instance
@@ -499,3 +499,16 @@ class Router(object):
req = Request(environ)
resp = self(req)
return resp(environ, start_response)
+
+ def _get_model_instance(self, model_cls, data):
+ try:
+ instance = model_cls(**data)
+ except TypeError as e:
+ # Throw a more user-friendly exception when input data is not an object
+ if 'type object argument after ** must be a mapping, not' in str(e):
+ msg = ('Input body needs to be an object, got: %s' % (type(data)))
+ raise ValueError(msg)
+
+ raise e
+
+ return instance
