# Buggy code
def __determine_job_destination(self, params, raw_job_destination=None):
    if raw_job_destination is None:
        raw_job_destination = self.job_wrapper.tool.get_job_destination(params)
    if raw_job_destination.runner == DYNAMIC_RUNNER_NAME:
        job_destination = self.__handle_dynamic_job_destination(raw_job_destination)
        log.debug(
            "(%s) Mapped job to destination id: %s",
            self.job_wrapper.job_id,
            job_destination.id,
        )
        # Recursively handle chained dynamic destinations
        if job_destination.runner == DYNAMIC_RUNNER_NAME:
            return self.__determine_job_destination(
                params, raw_job_destination=job_destination
            )
    else:
        job_destination = raw_job_destination
        log.debug(
            "(%s) Mapped job to destination id: %s",
            self.job_wrapper.job_id,
            job_destination.id,
        )
    return job_destination


# Traceback (AttributeError)
Traceback (most recent call last):
File "/opt/galaxy/server/lib/galaxy/jobs/handler.py", line 374, in __handle_waiting_jobs
job_state = self.__check_job_state(job)
File "/opt/galaxy/server/lib/galaxy/jobs/handler.py", line 510, in __check_job_state
state, job_destination = self.__verify_job_ready(job, job_wrapper)
File "/opt/galaxy/server/lib/galaxy/jobs/handler.py", line 534, in __verify_job_ready
job_wrapper.fail(e)
File "/opt/galaxy/server/lib/galaxy/jobs/__init__.py", line 1002, in fail
self.job_destination
File "/opt/galaxy/server/lib/galaxy/jobs/__init__.py", line 806, in job_destination
return self.job_runner_mapper.get_job_destination(self.params)
File "/opt/galaxy/server/lib/galaxy/jobs/mapper.py", line 235, in get_job_destination
return self.__cache_job_destination(params)
File "/opt/galaxy/server/lib/galaxy/jobs/mapper.py", line 225, in __cache_job_destination
params, raw_job_destination=raw_job_destination)
File "/opt/galaxy/server/lib/galaxy/jobs/mapper.py", line 211, in __determine_job_destination
raw_job_destination = self.job_wrapper.tool.get_job_destination(params)
AttributeError: 'NoneType' object has no attribute 'get_job_destination'

# Fixed code
def __determine_job_destination(self, params, raw_job_destination=None):
    if self.job_wrapper.tool is None:
        raise JobMappingException(
            "Can't map job to destination, tool '%s' is unavailable"
            % self.job_wrapper.get_job().tool_id
        )
    if raw_job_destination is None:
        raw_job_destination = self.job_wrapper.tool.get_job_destination(params)
    if raw_job_destination.runner == DYNAMIC_RUNNER_NAME:
        job_destination = self.__handle_dynamic_job_destination(raw_job_destination)
        log.debug(
            "(%s) Mapped job to destination id: %s",
            self.job_wrapper.job_id,
            job_destination.id,
        )
        # Recursively handle chained dynamic destinations
        if job_destination.runner == DYNAMIC_RUNNER_NAME:
            return self.__determine_job_destination(
                params, raw_job_destination=job_destination
            )
    else:
        job_destination = raw_job_destination
        log.debug(
            "(%s) Mapped job to destination id: %s",
            self.job_wrapper.job_id,
            job_destination.id,
        )
    return job_destination