# Buggy code
def processCall(self, session, call):
    """
    Implements :func:`crossbar.router.interfaces.IDealer.processCall`
    """
    if self._router.is_traced:
        if not call.correlation_id:
            call.correlation_id = self._router.new_correlation_id()
            call.correlation_is_anchor = True
            call.correlation_is_last = False
        if not call.correlation_uri:
            call.correlation_uri = call.procedure
        self._router._factory._worker._maybe_trace_rx_msg(session, call)

    # check procedure URI: for CALL, must be valid URI (either strict or loose), and
    # all URI components must be non-empty
    if self._option_uri_strict:
        uri_is_valid = _URI_PAT_STRICT_NON_EMPTY.match(call.procedure)
    else:
        uri_is_valid = _URI_PAT_LOOSE_NON_EMPTY.match(call.procedure)

    if not uri_is_valid:
        reply = message.Error(
            message.Call.MESSAGE_TYPE,
            call.request,
            ApplicationError.INVALID_URI,
            [
                "call with invalid procedure URI '{0}' (URI strict checking {1})".format(
                    call.procedure, self._option_uri_strict
                )
            ],
        )
        reply.correlation_id = call.correlation_id
        reply.correlation_uri = call.procedure
        reply.correlation_is_anchor = False
        reply.correlation_is_last = True
        self._router.send(session, reply)
        return

    # authorize CALL action
    #
    d = self._router.authorize(
        session, call.procedure, "call", options=call.marshal_options()
    )

    def on_authorize_success(authorization):
        # the call to authorize the action _itself_ succeeded. now go on depending on whether
        # the action was actually authorized or not ..
        #
        if not authorization["allow"]:
            reply = message.Error(
                message.Call.MESSAGE_TYPE,
                call.request,
                ApplicationError.NOT_AUTHORIZED,
                [
                    "session is not authorized to call procedure '{0}'".format(
                        call.procedure
                    )
                ],
            )
            reply.correlation_id = call.correlation_id
            reply.correlation_uri = call.procedure
            reply.correlation_is_anchor = False
            reply.correlation_is_last = True
            self._router.send(session, reply)

        else:
            # get registrations active on the procedure called
            #
            registration = self._registration_map.best_matching_observation(
                call.procedure
            )

            if registration:
                # validate payload (skip in "payload_transparency" mode)
                #
                if call.payload is None:
                    try:
                        self._router.validate(
                            "call", call.procedure, call.args, call.kwargs
                        )
                    except Exception as e:
                        reply = message.Error(
                            message.Call.MESSAGE_TYPE,
                            call.request,
                            ApplicationError.INVALID_ARGUMENT,
                            [
                                "call of procedure '{0}' with invalid application payload: {1}".format(
                                    call.procedure, e
                                )
                            ],
                        )
                        reply.correlation_id = call.correlation_id
                        reply.correlation_uri = call.procedure
                        reply.correlation_is_anchor = False
                        reply.correlation_is_last = True
                        self._router.send(session, reply)
                        return

                # now actually perform the invocation of the callee ..
                #
                self._call(session, call, registration, authorization)
            else:
                reply = message.Error(
                    message.Call.MESSAGE_TYPE,
                    call.request,
                    ApplicationError.NO_SUCH_PROCEDURE,
                    ["no callee registered for procedure <{0}>".format(call.procedure)],
                )
                reply.correlation_id = call.correlation_id
                reply.correlation_uri = call.procedure
                reply.correlation_is_anchor = False
                reply.correlation_is_last = True
                self._router.send(session, reply)

    def on_authorize_error(err):
        """
        the call to authorize the action _itself_ failed (note this is
        different from the call to authorize succeed, but the
        authorization being denied)
        """
        self.log.failure(
            "Authorization of 'call' for '{uri}' failed",
            uri=call.procedure,
            failure=err,
        )
        reply = message.Error(
            message.Call.MESSAGE_TYPE,
            call.request,
            ApplicationError.AUTHORIZATION_FAILED,
            [
                "failed to authorize session for calling procedure '{0}': {1}".format(
                    call.procedure, err.value
                )
            ],
        )
        reply.correlation_id = call.correlation_id
        reply.correlation_uri = call.procedure
        reply.correlation_is_anchor = False
        reply.correlation_is_last = True
        self._router.send(session, reply)

    txaio.add_callbacks(d, on_authorize_success, on_authorize_error)


# Traceback (builtins.KeyError)
Unhandled error in Deferred:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/autobahn/wamp/protocol.py", line 888, in onMessage
txaio.resolve(on_reply, msg.args[0])
File "/usr/local/lib/python3.6/dist-packages/txaio/tx.py", line 468, in resolve
future.callback(result)
File "/usr/local/lib/python3.6/dist-packages/twisted/internet/defer.py", line 460, in callback
self._startRunCallbacks(result)
File "/usr/local/lib/python3.6/dist-packages/twisted/internet/defer.py", line 568, in _startRunCallbacks
self._runCallbacks()
--- <exception caught here> ---
File "/usr/local/lib/python3.6/dist-packages/twisted/internet/defer.py", line 654, in _runCallbacks
current.result = callback(current.result, *args, **kw)
File "/usr/local/lib/python3.6/dist-packages/crossbar/router/dealer.py", line 441, in on_authorize_success
self._session_to_registrations[session].add(registration)
builtins.KeyError: <crossbar.router.session.RouterSession object at 0x7f653abfaef0>

# Fixed code
def processCall(self, session, call):
    """
    Implements :func:`crossbar.router.interfaces.IDealer.processCall`
    """
    if self._router.is_traced:
        if not call.correlation_id:
            call.correlation_id = self._router.new_correlation_id()
            call.correlation_is_anchor = True
            call.correlation_is_last = False
        if not call.correlation_uri:
            call.correlation_uri = call.procedure
        self._router._factory._worker._maybe_trace_rx_msg(session, call)

    # check procedure URI: for CALL, must be valid URI (either strict or loose), and
    # all URI components must be non-empty
    if self._option_uri_strict:
        uri_is_valid = _URI_PAT_STRICT_NON_EMPTY.match(call.procedure)
    else:
        uri_is_valid = _URI_PAT_LOOSE_NON_EMPTY.match(call.procedure)

    if not uri_is_valid:
        reply = message.Error(
            message.Call.MESSAGE_TYPE,
            call.request,
            ApplicationError.INVALID_URI,
            [
                "call with invalid procedure URI '{0}' (URI strict checking {1})".format(
                    call.procedure, self._option_uri_strict
                )
            ],
        )
        reply.correlation_id = call.correlation_id
        reply.correlation_uri = call.procedure
        reply.correlation_is_anchor = False
        reply.correlation_is_last = True
        self._router.send(session, reply)
        return

    # authorize CALL action
    #
    d = self._router.authorize(
        session, call.procedure, "call", options=call.marshal_options()
    )

    def on_authorize_success(authorization):
        # the call to authorize the action _itself_ succeeded. now go on depending on whether
        # the action was actually authorized or not ..
        #
        if not authorization["allow"]:
            reply = message.Error(
                message.Call.MESSAGE_TYPE,
                call.request,
                ApplicationError.NOT_AUTHORIZED,
                [
                    "session is not authorized to call procedure '{0}'".format(
                        call.procedure
                    )
                ],
            )
            reply.correlation_id = call.correlation_id
            reply.correlation_uri = call.procedure
            reply.correlation_is_anchor = False
            reply.correlation_is_last = True
            self._router.send(session, reply)

        else:
            # get registrations active on the procedure called
            #
            registration = self._registration_map.best_matching_observation(
                call.procedure
            )

            # if the session disconencted while the authorization
            # was being checked, 'registration' will be None and
            # we'll (correctly) fire an error.

            if registration:
                # validate payload (skip in "payload_transparency" mode)
                #
                if call.payload is None:
                    try:
                        self._router.validate(
                            "call", call.procedure, call.args, call.kwargs
                        )
                    except Exception as e:
                        reply = message.Error(
                            message.Call.MESSAGE_TYPE,
                            call.request,
                            ApplicationError.INVALID_ARGUMENT,
                            [
                                "call of procedure '{0}' with invalid application payload: {1}".format(
                                    call.procedure, e
                                )
                            ],
                        )
                        reply.correlation_id = call.correlation_id
                        reply.correlation_uri = call.procedure
                        reply.correlation_is_anchor = False
                        reply.correlation_is_last = True
                        self._router.send(session, reply)
                        return

                # now actually perform the invocation of the callee ..
                #
                self._call(session, call, registration, authorization)
            else:
                reply = message.Error(
                    message.Call.MESSAGE_TYPE,
                    call.request,
                    ApplicationError.NO_SUCH_PROCEDURE,
                    ["no callee registered for procedure <{0}>".format(call.procedure)],
                )
                reply.correlation_id = call.correlation_id
                reply.correlation_uri = call.procedure
                reply.correlation_is_anchor = False
                reply.correlation_is_last = True
                self._router.send(session, reply)

    def on_authorize_error(err):
        """
        the call to authorize the action _itself_ failed (note this is
        different from the call to authorize succeed, but the
        authorization being denied)
        """
        self.log.failure(
            "Authorization of 'call' for '{uri}' failed",
            uri=call.procedure,
            failure=err,
        )
        reply = message.Error(
            message.Call.MESSAGE_TYPE,
            call.request,
            ApplicationError.AUTHORIZATION_FAILED,
            [
                "failed to authorize session for calling procedure '{0}': {1}".format(
                    call.procedure, err.value
                )
            ],
        )
        reply.correlation_id = call.correlation_id
        reply.correlation_uri = call.procedure
        reply.correlation_is_anchor = False
        reply.correlation_is_last = True
        self._router.send(session, reply)

    txaio.add_callbacks(d, on_authorize_success, on_authorize_error)