docstr: Execute :meth:`save_result` for all classes in :attr:`recorders`
  
  Notes
  -----
  When iterating through :attr:`recorders` and calling :meth:`save_result`, a check is
  performed for `exit_code`. Children classes of :class:`BaseRecorder` are NOT expected to
  explicitly return a value in their :meth:`save_result`. However, if a value is returned and
  `exit_code` == 'break', the result-saving loop will be broken, and no further results will
  be saved. In practice, this is only performed for the sake of
  :meth:`DescriptionRecorder.save_result`, which has the additional quality of being able to
  prevent any other result files from being saved if the result of
  :func:`DescriptionRecorder.do_full_save` returns False when given the formatted
  :attr:`DescriptionRecorder.result`. This can be useful when there are storage constraints,
  because it ensures that essential data - including keys and the results of the experiment -
  are saved (to ensure the experiment is not duplicated, and to enable optimization protocol
  learning), while extra results like Predictions are not saved
docstr_tok: ["Execute",":","meth",":","`","save_result","`","for","all","classes","in",":","attr",":","`","recorders","`","Notes","--","--","-","When","iterating","through",":","attr",":","`","recorders","`","and","calling",":","meth",":","`","save_result","`",",","a","check","is","performed","for","`","exit_code","`",".","Children","classes","of",":","class",":","`","BaseRecorder","`","are","NOT","expected","to","explicitly","return","a","value","in","their",":","meth",":","`","save_result","`",".","However",",","if","a","value","is","returned","and","`","exit_code","`","==","'break","'",",","the","result-saving","loop","will","be","broken",",","and","no","further","results","will","be","saved",".","In","practice",",","this","is","only","performed","for","the","sake","of",":","meth",":","`","DescriptionRecorder.save_result","`",",","which","has","the","additional","quality","of","being","able","to","prevent","any","other","result","files","from","being","saved","if","the","result","of",":","func",":","`","DescriptionRecorder.do_full_save","`","returns","False","when","given","the","formatted",":","attr",":","`","DescriptionRecorder.result","`",".","This","can","be","useful","when","there","are","storage","constraints",",","because","it","ensures","that","essential","data","-","including","keys","and","the","results","of","the","experiment","-","are","saved","(","to","ensure","the","experiment","is","not","duplicated",",","and","to","enable","optimization","protocol","learning",")",",","while","extra","results","like","Predictions","are","not","saved"]
code: def save_result(self):
      """Execute :meth:`save_result` for all classes in :attr:`recorders`
  
      Notes
      -----
      When iterating through :attr:`recorders` and calling :meth:`save_result`, a check is
      performed for `exit_code`. Children classes of :class:`BaseRecorder` are NOT expected to
      explicitly return a value in their :meth:`save_result`. However, if a value is returned and
      `exit_code` == 'break', the result-saving loop will be broken, and no further results will
      be saved. In practice, this is only performed for the sake of
      :meth:`DescriptionRecorder.save_result`, which has the additional quality of being able to
      prevent any other result files from being saved if the result of
      :func:`DescriptionRecorder.do_full_save` returns False when given the formatted
      :attr:`DescriptionRecorder.result`. This can be useful when there are storage constraints,
      because it ensures that essential data - including keys and the results of the experiment -
      are saved (to ensure the experiment is not duplicated, and to enable optimization protocol
      learning), while extra results like Predictions are not saved"""
      for recorder in self.recorders:
          G.log(
              f"Saving result file for '{type(recorder).__name__}'", 4
          )
          exit_code = recorder.save_result()
  
          if exit_code and exit_code == "break":
              break
  
imports: from hyperparameter_hunter.data import OOFDataset, HoldoutDataset, TestDataset
  from hyperparameter_hunter.i_o.exceptions import EnvironmentInactiveError, EnvironmentInvalidError
  from hyperparameter_hunter.i_o.leaderboards import GlobalLeaderboard
  from hyperparameter_hunter.settings import G
  from hyperparameter_hunter.utils.file_utils import write_json, add_to_json, make_dirs, read_json
  from hyperparameter_hunter.utils.file_utils import RetryMakeDirs
  from hyperparameter_hunter.utils.general_utils import subdict
  from abc import ABCMeta, abstractmethod
  from collections import OrderedDict
  from platform import node
  import shutil
  from sys import exc_info
label_desc: Use image node_id 3 for calling the RecorderList obj's underlying member method code with example usage: obj.save_result() without return types