class ManifestPusher implements RegistryEndpointProvider<DescriptorDigest> {

  @Override
  public DescriptorDigest handleHttpResponseException(ResponseException responseException)
      throws ResponseException, RegistryErrorException {
    // docker registry 2.0 and 2.1 returns:
    //   400 Bad Request
    //   {"errors":[{"code":"TAG_INVALID","message":"manifest tag did not match URI"}]}
    // docker registry:2.2 returns:
    //   400 Bad Request
    //   {"errors":[{"code":"MANIFEST_INVALID","message":"manifest invalid","detail":{}}]}
    // quay.io returns:
    //   415 UNSUPPORTED MEDIA TYPE
    //   {"errors":[{"code":"MANIFEST_INVALID","detail":
    //   {"message":"manifest schema version not supported"},"message":"manifest invalid"}]}

    if (responseException.getStatusCode() != HttpStatus.SC_BAD_REQUEST
        && responseException.getStatusCode() != HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE) {
      throw responseException;
    }

    ErrorCodes errorCode = ErrorResponseUtil.getErrorCode(responseException);
    if (errorCode == ErrorCodes.MANIFEST_INVALID || errorCode == ErrorCodes.TAG_INVALID) {
      throw new RegistryErrorExceptionBuilder(getActionDescription(), responseException)
          .addReason(
              "Registry may not support pushing OCI Manifest or "
                  + "Docker Image Manifest Version 2, Schema 2")
          .build();
    }
    // rethrow: unhandled error response code.
    throw responseException;
  }

    ManifestPusher(
      RegistryEndpointRequestProperties registryEndpointRequestProperties,
      ManifestTemplate manifestTemplate,
      String imageTag,
      EventHandlers eventHandlers);

}