code: def _gather_metrics(
      repo: "Repo",
      targets: Optional[List[str]] = None,
      outs_only: bool = False,
      stages: Optional[List[str]] = None,
      on_error: str = "return",
  ) -> Dict[str, FileResult]:
      assert on_error in ("raise", "return", "ignore")
  
      # `files` is a repo-relative posixpath that can be passed to DVCFileSystem
      # It is absolute, i.e. has a root_marker `/` in front which we strip when returning
      # the result and convert to appropriate repo-relative os.path.
      files = _collect_metrics(
          repo, targets=targets, stages=stages, outs_only=outs_only
      )
      data = {}
  
      fs = repo.dvcfs
      for fs_path, result in _read_metrics(fs, files, cache=True):
          repo_path = fs_path.lstrip(fs.root_marker)
          repo_os_path = os.sep.join(fs.parts(repo_path))
          if not isinstance(result, Exception):
              data.update({repo_os_path: FileResult(data=result)})
              continue
  
          if on_error == "raise":
              raise result
          if on_error == "return":
              data.update({repo_os_path: FileResult(error=result)})
      return data
  
imports: import os
  from itertools import chain
  from typing import TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Optional, Tuple, TypedDict, Union
  from funcy import ldistinct
  from scmrepo.exceptions import SCMError
  from dvc.log import logger
  from dvc.scm import NoSCMError
  from dvc.utils import as_posix, expand_paths
  from dvc.utils.collections import ensure_list
  from dvc.utils.serialize import load_path
label_desc: Use image node_id 8 for calling a global function with example usage: _gather_metrics(repo, targets, outs_only, stages, on_error) and returns: data