docs: def check_for_errors(config, raise_exception=True):
      """
      Returns config validation errors if raise_exception is False,
      otherwise raises ConfigurationError with those errors in it.
      Errors are represented as nested dicts (sections & options in them).
      """
      errors = {}
      for section in ['reader', 'writer', 'filter', 'filter_before',
                      'filter_after', 'transform', 'persistence',
                      'decompressor', 'deserializer']:
          config_section = config.get(section)
          if config_section is None:
              if section in REQUIRED_CONFIG_SECTIONS:
                  errors[section] = "Missing section"
          else:
              section_errors = _get_section_errors(config_section)
              if section_errors:
                  errors[section] = section_errors
  
      exporter_options = config.get('exporter_options', {})
      if "formatter" in exporter_options:
          section_errors = _get_section_errors(exporter_options['formatter'])
          if section_errors:
              errors['formatter'] = section_errors
  
      if not _is_stream_reader(config):
          for section in STREAM_READER_SECTIONS:
              if config.get(section) and not errors.get(section):
                  errors[section] = 'The %r section can only be used with a stream reader.' % section
  
      for i, notificator in enumerate(exporter_options.get('notifications', [])):
          section_errors = _get_section_errors(notificator)
          if section_errors:
              errors['notifications_' + str(i)] = section_errors
  
      if raise_exception and errors:
          raise ConfigCheckError(errors=errors)
      else:
          return errors