class_docstr: A backfill job runner consists of a dag or subdag for a specific time range.
  
  It triggers a set of task instance runs, in the right order and lasts for
  as long as it takes for the set of task instance to be completed.
code: def _collect_errors(
      self, ti_status: _DagRunTaskStatus, session: Session = NEW_SESSION
  ) -> Iterator[str]:
      def tabulate_ti_keys_set(
          ti_keys: Iterable[TaskInstanceKey],
      ) -> str:
          # Sorting by execution date first
          sorted_ti_keys: Any = sorted(
              ti_keys,
              key=lambda ti_key: (
                  ti_key.run_id,
                  ti_key.dag_id,
                  ti_key.task_id,
                  ti_key.map_index,
                  ti_key.try_number,
              ),
          )
  
          if all(key.map_index == -1 for key in ti_keys):
              headers = ["DAG ID", "Task ID", "Run ID", "Try number"]
              sorted_ti_keys = (k[0:4] for k in sorted_ti_keys)
          else:
              headers = [
                  "DAG ID",
                  "Task ID",
                  "Run ID",
                  "Map Index",
                  "Try number",
              ]
  
          return tabulate(sorted_ti_keys, headers=headers)
  
      if ti_status.failed:
          yield "Some task instances failed:\n"
          yield tabulate_ti_keys_set(ti_status.failed)
      if ti_status.deadlocked:
          yield "BackfillJob is deadlocked."
          deadlocked_depends_on_past = any(
              t.are_dependencies_met(
                  dep_context=DepContext(ignore_depends_on_past=False),
                  session=session,
                  verbose=self.verbose,
              )
              != t.are_dependencies_met(
                  dep_context=DepContext(ignore_depends_on_past=True),
                  session=session,
                  verbose=self.verbose,
              )
              for t in ti_status.deadlocked
          )
          if deadlocked_depends_on_past:
              yield (
                  "Some of the deadlocked tasks were unable to run because "
                  'of "depends_on_past" relationships. Try running the '
                  "backfill with the option "
                  '"ignore_first_depends_on_past=True" or passing "-I" at '
                  "the command line."
              )
          yield "\nThese tasks have succeeded:\n"
          yield tabulate_ti_keys_set(ti_status.succeeded)
          yield "\n\nThese tasks are running:\n"
          yield tabulate_ti_keys_set(ti_status.running)
          yield "\n\nThese tasks have failed:\n"
          yield tabulate_ti_keys_set(ti_status.failed)
          yield "\n\nThese tasks are skipped:\n"
          yield tabulate_ti_keys_set(ti_status.skipped)
          yield "\n\nThese tasks are deadlocked:\n"
          yield tabulate_ti_keys_set(
              [ti.key for ti in ti_status.deadlocked]
          )
  
imports: from __future__ import annotations
  import time
  from typing import TYPE_CHECKING, Any, Iterable, Iterator, Mapping, Sequence
  import attr
  import pendulum
  from sqlalchemy import select, tuple_, update
  from sqlalchemy.exc import OperationalError
  from sqlalchemy.orm.session import make_transient
  from tabulate import tabulate
  from airflow import models
  from airflow.exceptions import AirflowException, BackfillUnfinished, DagConcurrencyLimitReached, NoAvailablePoolSlot, PoolNotFound, TaskConcurrencyLimitReached
  from airflow.executors.executor_loader import ExecutorLoader
  from airflow.jobs.base_job_runner import BaseJobRunner
  from airflow.jobs.job import Job, perform_heartbeat
  from airflow.models import DAG, DagPickle
  from airflow.models.dagrun import DagRun
  from airflow.models.taskinstance import TaskInstance
  from airflow.ti_deps.dep_context import DepContext
  from airflow.ti_deps.dependencies_deps import BACKFILL_QUEUED_DEPS
  from airflow.timetables.base import DagRunInfo
  from airflow.utils import helpers, timezone
  from airflow.utils.configuration import conf, tmp_configuration_copy
  from airflow.utils.log.logging_mixin import LoggingMixin
  from airflow.utils.session import NEW_SESSION, provide_session
  from airflow.utils.state import DagRunState, State, TaskInstanceState
  from airflow.utils.types import DagRunType
label_desc: Use image node_id 8 for calling the BackfillJobRunner obj's underlying member method code with example usage: obj._collect_errors(ti_status, session) and returns: tabulate