Class KeyManagementSdkException

java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
co.ankatech.ankasecure.keymanagement.exception.KeyManagementSdkException
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
QuorumApprovalPendingException, TenantBindingRequiredException

public class KeyManagementSdkException extends RuntimeException
Uniform exception thrown by the public AnkaSecure Key Management SDK surface.

Carries the HTTP status returned by the Auth API or the Admin API when applicable. The message never contains credential material or bearer-token substrings: it is built from the operation context, the HTTP status, and the server's own RFC 9457 detail sentence, every server-supplied value in it rendered by TerminalSafe.text(String), so it is safe to log or print verbatim. The raw response body is never kept.

The problem and OAuth fields below hold the server's values as received, for programmatic use (classification, comparison). Code that prints one renders it through TerminalSafe first.

The cause is unrendered too. For a refused call it is the generated client's ApiException: its message is the server's HTTP reason phrase, and its getters keep the response body and headers, the Location of a 3xx included. Neither the cause nor a stack trace that prints it is written to a terminal or a log without rendering it through TerminalSafe; this exception's own message and toString() never include it.

When the remote API answered with an RFC 9457 problem+json body, its type, title, detail, instance and extension members are exposed as first-class fields. Classify on getProblemType(): the type URI is the stable contract; the message carries the human sentence and may be reworded by the server at any time.

When the Auth API refused a token request with an OAuth 2.0 error response (RFC 6749 section 5.2, RFC 9449 section 12.2), its error code (invalid_client, invalid_dpop_proof, invalid_request, ...) is exposed by getOAuthError(), and a Retry-After the server sent with a 503 by getRetryAfter().


 try {
     sdk.keys().create(request);
 } catch (KeyManagementSdkException e) {
     if (e.getHttpStatus() == 409 && e.getProblemType() != null && e.getProblemType().endsWith("/key-id-retired")) {
         // the Key ID belonged to a destroyed key of this tenant and is never reused
     }
 }
 
See Also:
  • Constructor Details

    • KeyManagementSdkException

      public KeyManagementSdkException(String message, Throwable cause)
      Creates an exception with a message and an underlying cause, without an HTTP status.
      Parameters:
      message - a log-safe description that MUST NOT contain secret or token material
      cause - the underlying cause, or null
    • KeyManagementSdkException

      public KeyManagementSdkException(String message, int httpStatus, Throwable cause)
      Creates an exception with a message, an HTTP status, and an underlying cause.
      Parameters:
      message - a log-safe description that MUST NOT contain secret or token material
      httpStatus - the HTTP status returned by the remote API
      cause - the underlying cause, or null
    • KeyManagementSdkException

      public KeyManagementSdkException(String message, int httpStatus, Throwable cause, String problemType, String problemTitle, String problemDetail, String oauthError, Duration retryAfter)
      Creates an exception for a refused token request, carrying the OAuth 2.0 error code and the server's Retry-After delay alongside the problem fields.
      Parameters:
      message - a log-safe description that MUST NOT contain secret or token material
      httpStatus - the HTTP status returned by the remote API
      cause - the underlying cause, or null
      problemType - the problem type URI, or null
      problemTitle - the problem title, or null
      problemDetail - the problem detail, or null
      oauthError - the OAuth 2.0 error code, or null
      retryAfter - the Retry-After delay the server sent, or null
    • KeyManagementSdkException

      public KeyManagementSdkException(String message, int httpStatus, Throwable cause, String problemType, String problemTitle, String problemDetail, String problemInstance, Map<String,Object> problemExtensions, String oauthError, Duration retryAfter)
      Creates an exception carrying every RFC 9457 member the response body held.
      Parameters:
      message - a log-safe description that MUST NOT contain secret or token material
      httpStatus - the HTTP status returned by the remote API
      cause - the underlying cause, or null
      problemType - the problem type URI, or null
      problemTitle - the problem title, or null
      problemDetail - the problem detail, or null
      problemInstance - the problem instance, or null
      problemExtensions - the extension members (String, Number, Boolean, List or Map values); null reads as empty
      oauthError - the OAuth 2.0 error code, or null
      retryAfter - the Retry-After delay the server sent, or null
  • Method Details

    • getHttpStatus

      public int getHttpStatus()
      Returns:
      the HTTP status associated with this failure, or 0 when not HTTP-related
    • getProblemType

      public String getProblemType()
      Returns the RFC 9457 type URI identifying the problem. This is the stable classification key: classify on it rather than on Throwable.getMessage().

      Server-supplied and unrendered, for programmatic use: a caller that displays it renders it through TerminalSafe.text(String) (or TerminalSafe.uri(String) for a URI). The message never carries it unrendered.

      Returns:
      the problem type URI, or null when the response carried no problem body
    • getProblemTitle

      public String getProblemTitle()
      Server-supplied and unrendered, for programmatic use: a caller that displays it renders it through TerminalSafe.text(String) (or TerminalSafe.uri(String) for a URI). The message never carries it unrendered.
      Returns:
      the RFC 9457 title of the problem, or null when absent
    • getProblemDetail

      public String getProblemDetail()
      Server-supplied and unrendered, for programmatic use: a caller that displays it renders it through TerminalSafe.text(String) (or TerminalSafe.uri(String) for a URI). The message never carries it unrendered.
      Returns:
      the RFC 9457 detail of the problem, or null when absent
    • getProblemInstance

      public String getProblemInstance()
      Server-supplied and unrendered, for programmatic use: a caller that displays it renders it through TerminalSafe.text(String) (or TerminalSafe.uri(String) for a URI). The message never carries it unrendered.
      Returns:
      the RFC 9457 instance of the problem (the request path the server refused), or null when absent
    • getProblemExtensions

      public Map<String,Object> getProblemExtensions()
      Returns the problem's extension members. The Admin API nests them under extensions (for example requestId, the correlation id to quote to support, and field, the member a validation refused); members of that object and any other top-level member beyond the five RFC 9457 members are returned here, by name.

      Server-supplied and unrendered, for programmatic use: a caller that displays it renders it through TerminalSafe.text(String) (or TerminalSafe.uri(String) for a URI). The message never carries it unrendered.

      Returns:
      the extension members, never null; empty when the body carried none
    • getOAuthError

      public String getOAuthError()
      Returns the OAuth 2.0 error code of a refused token request: invalid_client (the workload credential was refused), invalid_dpop_proof (the DPoP proof was refused) or invalid_request (a token request the authorization server could not accept as formed).

      Server-supplied and unrendered, for programmatic use: a caller that displays it renders it through TerminalSafe.text(String) (or TerminalSafe.uri(String) for a URI). The message never carries it unrendered.

      Returns:
      the error code, or null when the failure was not an OAuth error response
    • getRetryAfter

      public Optional<Duration> getRetryAfter()
      Returns how long the server asked the caller to wait before retrying, from the Retry-After header of a 503 answer.
      Returns:
      the delay, or empty when the response carried no Retry-After