Module: KubeMQ::ErrorMapper

Defined in:
lib/kubemq/errors/error_mapper.rb

Overview

Maps gRPC GRPC::BadStatus exceptions to typed Error subclasses.

Used internally by Interceptors::ErrorMappingInterceptor and subscription reconnect loops. Application code should rescue Error subclasses rather than raw gRPC exceptions.

gRPC Status Code Mapping

gRPC Code SDK Exception Error Code Retryable?
CANCELLED CancellationError CANCELLED No
UNKNOWN Error UNKNOWN Yes
INVALID_ARGUMENT ValidationError VALIDATION_ERROR No
DEADLINE_EXCEEDED TimeoutError CONNECTION_TIMEOUT Yes
NOT_FOUND ChannelError NOT_FOUND No
ALREADY_EXISTS ValidationError ALREADY_EXISTS No
PERMISSION_DENIED AuthenticationError PERMISSION_DENIED No
RESOURCE_EXHAUSTED MessageError RESOURCE_EXHAUSTED Yes
FAILED_PRECONDITION ValidationError VALIDATION_ERROR No
ABORTED TransactionError ABORTED Yes
OUT_OF_RANGE ValidationError OUT_OF_RANGE No
UNIMPLEMENTED Error UNIMPLEMENTED No
INTERNAL Error INTERNAL No
UNAVAILABLE ConnectionError UNAVAILABLE Yes
DATA_LOSS Error DATA_LOSS No
UNAUTHENTICATED AuthenticationError AUTH_FAILED No

See Also:

Constant Summary collapse

GRPC_MAPPING =

Maps gRPC status codes to [exception_class, error_code, retryable] tuples.

Returns:

  • (Hash{Integer => Array(Class, String, Boolean)})
{
  GRPC::Core::StatusCodes::CANCELLED =>
    [CancellationError, ErrorCode::CANCELLED, false],
  GRPC::Core::StatusCodes::UNKNOWN =>
    [KubeMQ::Error, ErrorCode::UNKNOWN, true],
  GRPC::Core::StatusCodes::INVALID_ARGUMENT =>
    [ValidationError, ErrorCode::VALIDATION_ERROR, false],
  GRPC::Core::StatusCodes::DEADLINE_EXCEEDED =>
    [KubeMQ::TimeoutError, ErrorCode::CONNECTION_TIMEOUT, true],
  GRPC::Core::StatusCodes::NOT_FOUND =>
    [ChannelError, ErrorCode::NOT_FOUND, false],
  GRPC::Core::StatusCodes::ALREADY_EXISTS =>
    [ValidationError, ErrorCode::ALREADY_EXISTS, false],
  GRPC::Core::StatusCodes::PERMISSION_DENIED =>
    [AuthenticationError, ErrorCode::PERMISSION_DENIED, false],
  GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED =>
    [MessageError, ErrorCode::RESOURCE_EXHAUSTED, true],
  GRPC::Core::StatusCodes::FAILED_PRECONDITION =>
    [ValidationError, ErrorCode::VALIDATION_ERROR, false],
  GRPC::Core::StatusCodes::ABORTED =>
    [TransactionError, ErrorCode::ABORTED, true],
  GRPC::Core::StatusCodes::OUT_OF_RANGE =>
    [ValidationError, ErrorCode::OUT_OF_RANGE, false],
  GRPC::Core::StatusCodes::UNIMPLEMENTED =>
    [KubeMQ::Error, ErrorCode::UNIMPLEMENTED, false],
  GRPC::Core::StatusCodes::INTERNAL =>
    [KubeMQ::Error, ErrorCode::INTERNAL, false],
  GRPC::Core::StatusCodes::UNAVAILABLE =>
    [ConnectionError, ErrorCode::UNAVAILABLE, true],
  GRPC::Core::StatusCodes::DATA_LOSS =>
    [KubeMQ::Error, ErrorCode::DATA_LOSS, false],
  GRPC::Core::StatusCodes::UNAUTHENTICATED =>
    [AuthenticationError, ErrorCode::AUTH_FAILED, false]
}.freeze
CREDENTIAL_PATTERNS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Regex patterns for detecting credentials in error messages.

[
  /(?:bearer|authorization)\s*[:=]\s*\S+(?:\s+\S+)?/i,
  /eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/
].freeze

Class Method Summary collapse

Class Method Details

.map_grpc_error(error, operation: nil) ⇒ Error

Converts a GRPC::BadStatus exception to the appropriate KubeMQ::Error subclass.

Credential patterns (bearer tokens, JWTs) are scrubbed from error messages before constructing the exception. Falls back to KubeMQ::Error with UNKNOWN code for unmapped gRPC status codes.

Parameters:

  • error (GRPC::BadStatus)

    the gRPC exception to map

  • operation (String, nil) (defaults to: nil)

    the SDK operation name for context

Returns:

  • (Error)

    a typed SDK error with code, suggestion, and cause chain



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/kubemq/errors/error_mapper.rb', line 94

def map_grpc_error(error, operation: nil)
  mapping = GRPC_MAPPING[error.code]
  unless mapping
    return KubeMQ::Error.new(
      scrub_credentials(error.details || error.message),
      code: ErrorCode::UNKNOWN,
      cause: error,
      operation: operation
    )
  end

  exc_class, error_code, retryable = mapping
  suggestion = KubeMQ.suggestion_for(error_code)

  exc_class.new(
    scrub_credentials(error.details || error.message),
    code: error_code,
    retryable: retryable,
    cause: error,
    operation: operation,
    suggestion: suggestion
  )
end

.scrub_credentials(text) ⇒ String

Removes credential patterns from an error message string.

Matches bearer/authorization headers and JWT tokens, replacing them with [REDACTED].

Parameters:

  • text (String, nil)

    the text to scrub

Returns:

  • (String)

    the scrubbed text, or an empty string if text is nil



126
127
128
129
130
131
132
# File 'lib/kubemq/errors/error_mapper.rb', line 126

def scrub_credentials(text)
  return '' if text.nil?

  result = text.to_s
  CREDENTIAL_PATTERNS.each { |pattern| result = result.gsub(pattern, '[REDACTED]') }
  result
end