# Buggy code
def create_reader(
    self,
    session_id,
    data_key,
    source_devices,
    packed=False,
    packed_compression=None,
    _promise=True,
):
    """
    Create a data reader from existing data and return in a Promise.
    If no readers can be created, will try copying the data into a
    readable storage.

    :param session_id: session id
    :param data_key: data key
    :param source_devices: devices to read from
    :param packed: create a reader to read packed data format
    :param packed_compression: compression format to use when reading as packed
    :param _promise: return a promise
    """
    source_devices = self._normalize_devices(source_devices)
    stored_devs = set(self._manager_ref.get_data_locations(session_id, [data_key])[0])
    for src_dev in source_devices:
        if src_dev not in stored_devs:
            continue
        handler = self.get_storage_handler(src_dev)
        try:
            logger.debug(
                "Creating %s reader for (%s, %s) on %s",
                "packed" if packed else "bytes",
                session_id,
                data_key,
                handler.storage_type,
            )
            return handler.create_bytes_reader(
                session_id,
                data_key,
                packed=packed,
                packed_compression=packed_compression,
                _promise=_promise,
            )
        except AttributeError:  # pragma: no cover
            raise IOError(f"Device {src_dev} does not support direct reading.")

    if _promise:
        return self.copy_to(session_id, [data_key], source_devices).then(
            lambda *_: self.create_reader(
                session_id, data_key, source_devices, packed=packed
            )
        )
    else:
        raise IOError("Cannot return a non-promise result")


# Traceback (KeyError)
2020-12-02 11:19:40,309 mars.scheduler.operands.common 87 ERROR    Attempt 1: Unexpected error KeyError occurred in executing operand 5c7a3b06d448300987640036d2f5a34e in 11.238.145.234:49708
Traceback (most recent call last):
File "/home/admin/work/_public-mars-0.5.5.zip/mars/promise.py", line 378, in _wrapped
return func(*args, **kwargs)
File "/home/admin/work/_public-mars-0.5.5.zip/mars/utils.py", line 377, in _wrapped
return func(*args, **kwargs)
File "/home/admin/work/_public-mars-0.5.5.zip/mars/worker/execution.py", line 564, in execute_graph
quota_request = self._prepare_quota_request(session_id, graph_key)
File "/home/admin/work/_public-mars-0.5.5.zip/mars/worker/execution.py", line 249, in _prepare_quota_request
memory_estimations = self._estimate_calc_memory(session_id, graph_key)
File "/home/admin/work/_public-mars-0.5.5.zip/mars/worker/execution.py", line 213, in _estimate_calc_memory
res = executor.execute_graph(graph_record.graph, graph_record.chunk_targets, mock=True)
File "/home/admin/work/_public-mars-0.5.5.zip/mars/executor.py", line 690, in execute_graph
res = graph_execution.execute(retval)
File "/home/admin/work/_public-mars-0.5.5.zip/mars/executor.py", line 574, in execute
return [self._chunk_results[key] for key in self._keys]
File "/home/admin/work/_public-mars-0.5.5.zip/mars/executor.py", line 574, in <listcomp>
return [self._chunk_results[key] for key in self._keys]
KeyError: '3990ec90331559138b6ecbc6d76fbd0d'

# Fixed code
def create_reader(
    self,
    session_id,
    data_key,
    source_devices,
    packed=False,
    packed_compression=None,
    _promise=True,
):
    """
    Create a data reader from existing data and return in a Promise.
    If no readers can be created, will try copying the data into a
    readable storage.

    :param session_id: session id
    :param data_key: data key
    :param source_devices: devices to read from
    :param packed: create a reader to read packed data format
    :param packed_compression: compression format to use when reading as packed
    :param _promise: return a promise
    """
    source_devices = self._normalize_devices(source_devices)
    stored_devs = set(self._manager_ref.get_data_locations(session_id, [data_key])[0])
    for src_dev in source_devices:
        if src_dev not in stored_devs:
            continue
        handler = self.get_storage_handler(src_dev)
        try:
            logger.debug(
                "Creating %s reader for (%s, %s) on %s",
                "packed" if packed else "bytes",
                session_id,
                data_key,
                handler.storage_type,
            )
            return handler.create_bytes_reader(
                session_id,
                data_key,
                packed=packed,
                packed_compression=packed_compression,
                _promise=_promise,
            )
        except AttributeError:  # pragma: no cover
            raise IOError(f"Device {src_dev} does not support direct reading.")

    if _promise:
        return self.copy_to(session_id, [data_key], source_devices).then(
            lambda *_: self.create_reader(
                session_id, data_key, source_devices, packed=packed
            )
        )
    else:
        raise IOError(
            f"Cannot return a non-promise result for key {data_key}, stored_devs {stored_devs!r}"
        )