Package: nameko-worker-postmortem
nameko-worker-postmortemHave you ever been frustrated with the behaviour of a Nameko service in pytest using the--pdbflag?If your Nameko service throws a worker exception,--pdbwon't interrupt with a breakpoint until the exception is serialised back to the caller of the entrypoint.nameko-worker-postmortemis a pytest plugin that inserts the tracepoint earlier, so you can see a more useful stack trace.ExampleHere's an example test that will fail:# test.pyfromnameko.web.handlersimporthttpclassBadRequest(Exception):passclassService:name="service"@http("GET","/resource")defresource(self,request):param=request.args.get('param')ifparam=="good":return200,"OK"raiseBadRequest()deftest_service(container_factory,web_config,web_session):container=container_factory(Service,web_config)container.start()res=web_session.get('/resource?param=bad')assertres.status_code==200With--pdbUsing the--pdbflag, the breakpoint is set where the assertion fails, which isn't very helpful if you want to see the exception that the worker raised instead:$ py.test test.py============================= test session starts ==============================platform darwin -- Python 3.4.6, pytest-3.7.4, py-1.6.0, pluggy-0.7.1rootdir: /private/tmp, inifile:plugins: nameko-2.11.0, nameko-worker-postmortem-0.0.1collected 1 itemtest.py F>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> captured log >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>containers.py              399 ERROR    error handling worker <WorkerContext [service.resource] at 0x1104a77f0>:Traceback (most recent call last):File"/Users/mattbennett/.virtualenvs/tmp-302905cac73c0a2/lib/python3.4/site-packages/nameko/containers.py", line391, in_run_workerresult=method(*worker_ctx.args,**worker_ctx.kwargs)File"/private/tmp/test.py", line14, inresourceraiseBadRequest()test.BadRequest>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>container_factory = <function container_factory.<locals>.make_container at 0x11022f620>web_config = {'WEB_SERVER_ADDRESS':'127.0.0.1:55934'}web_session = <nameko.testing.pytest.web_session.<locals>.WebSession object at 0x11047ac18>def test_service(container_factory, web_config, web_session):container = container_factory(Service, web_config)container.start()res = web_session.get('/resource?param=bad')>       assert res.status_code == 200E       assert 500 == 200E        +  where 500 = <Response [500]>.status_codetest.py:22: AssertionError>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[11] > /private/tmp/test.py(22)test_service()-> assert res.status_code == 2006 frames hidden (try 'help hidden_frames')> /private/tmp/test.py(22)17     def test_service(container_factory, web_config, web_session):18         container = container_factory(Service, web_config)19         container.start()2021         res = web_session.get('/resource?param=bad')22  ->     assert res.status_code == 200With--worker-postmortemReplacing--pdbwith--worker-postmortem(or--worker-pdb) the breakpoint is inserted at where the worker exception is raised instead.Note that-smust also be passed to disable output capturing.$ py.test test.py --worker-postmortem -s
============================= test session starts ==============================
platform darwin -- Python 3.4.6, pytest-3.7.4, py-1.6.0, pluggy-0.7.1
rootdir: /private/tmp, inifile:
plugins: nameko-2.11.0, nameko-worker-postmortem-0.0.1
collected 1 item

test.py [1] > /private/tmp/test.py(14)resource()
-> raise BadRequest()
> /private/tmp/test.py(14)

   9         @http("GET", "/resource")
  10         def resource(self, request):
  11             param = request.args.get('param')
  12             if param == "good":
  13                 return 200, "OK"
  14  ->         raise BadRequest()
(Pdb++)TODOFix coverage collectionAdd pre-commit hooksAutomatically disable capturing so you don't have to specify-severy timeAttempt to make navigationupanddownthe stack trace work as they would with apdb.set_trace()(at the moment,updoesn't take you up the stack but into thenameko-worker-postmortemcode that inserts the breakpoint.)