Amin Etesamian Amin Etesamian - 1 year ago 52
Python Question

TypeErrpr is raised when using `abort(404)`

When I use

abort(status_code=404, detail='No such user', passthrough='json')

This exception is raised:

TypeError: 'NoneType' object is not iterable

This is the traceback:

File "/home/jugger/.virtualenvs/ave/lib/python3.5/site-packages/tg/appwrappers/identity.py", line 47, in __call__
return self.next_handler(controller, environ, context)
File "/home/jugger/.virtualenvs/ave/lib/python3.5/site-packages/tg/appwrappers/i18n.py", line 71, in __call__
return self.next_handler(controller, environ, context)
File "/home/jugger/.virtualenvs/ave/lib/python3.5/site-packages/tg/wsgiapp.py", line 285, in _dispatch
return controller(environ, context)
File "/home/jugger/workspace/web/ave/ave/lib/base.py", line 27, in __call__
return TGController.__call__(self, environ, context)
File "/home/jugger/.virtualenvs/ave/lib/python3.5/site-packages/tg/controllers/dispatcher.py", line 119, in __call__
response = self._perform_call(context)
File "/home/jugger/.virtualenvs/ave/lib/python3.5/site-packages/tg/controllers/dispatcher.py", line 108, in _perform_call
r = self._call(action, params, remainder=remainder, context=context)
File "/home/jugger/.virtualenvs/ave/lib/python3.5/site-packages/tg/controllers/decoratedcontroller.py", line 125, in _call
response = self._render_response(context, controller, output)
File "/home/jugger/.virtualenvs/ave/lib/python3.5/site-packages/tg/controllers/decoratedcontroller.py", line 220, in _render_response
for name in exclude_names:
TypeError: 'NoneType' object is not iterable
--------------------- >> end captured logging << ---------------------


This is my code:
I try to get an account that doesn't exist, so
NoResultFound
is caught and as the result
abort
must be done. but it raises the exception I mentioned above.

@expose('json')
def get_one(self, account_id):
"""
Get an account

:param account_id :type: str

:return Account :type: dict
"""
try:
_id = int(account_id)
except ValueError:
abort(status_code=400, detail='account_id must be int', passthrough='json')
try:
account = DBSession.query(Account).filter(Account.id == _id).one()
except NoResultFound:
abort(status_code=404, detail='No such user', passthrough='json')
return dict(
id=account.id,
username=account.username,
reputation=account.reputation,
badges=account.badges,
created=account.created,
bio=account.bio
)

Answer Source

according to this link, 404 is handled by the custom errors controller by default so the solution is to add expose('json') to your ErrorController and also add

if resp.content_type == 'application/json':
    return resp

after line 25 in ErrorController. This solves the issue with abort(404, passthrough='json') but I still think this is a bug and has to be fixed.