Module: BrainzLab::ErrorHandler
- Defined in:
- lib/brainzlab/errors.rb
Overview
Helper module for wrapping low-level errors into structured BrainzLab errors
Class Method Summary collapse
-
.from_response(response, service:, operation:) ⇒ BrainzLab::Error
Convert an HTTP response to a structured error.
- .parse_response_body(response) ⇒ Object
-
.wrap(error, service:, operation:) ⇒ BrainzLab::Error
Wrap a standard error into a structured BrainzLab error.
Class Method Details
.from_response(response, service:, operation:) ⇒ BrainzLab::Error
Convert an HTTP response to a structured error.
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 |
# File 'lib/brainzlab/errors.rb', line 414 def from_response(response, service:, operation:) status_code = response.code.to_i body = parse_response_body(response) = body[:message] || body[:error] || "HTTP #{status_code}" request_id = response['X-Request-Id'] case status_code when 400 ValidationError.new( , hint: body[:hint] || 'Check the request parameters.', code: body[:code] || 'bad_request', context: { service: service, operation: operation, status_code: status_code } ) when 401 AuthenticationError.new( , hint: body[:hint] || "Verify your #{service} API key is correct and active.", code: body[:code] || 'unauthorized', context: { service: service, operation: operation } ) when 403 AuthenticationError.new( , hint: body[:hint] || 'Your API key does not have permission for this operation.', code: body[:code] || 'forbidden', context: { service: service, operation: operation } ) when 404 NotFoundError.new( , hint: body[:hint] || 'The requested resource does not exist.', code: body[:code] || 'not_found', context: { service: service, operation: operation } ) when 422 ValidationError.new( , hint: body[:hint] || 'The request was well-formed but contained invalid data.', code: body[:code] || 'unprocessable_entity', errors: body[:errors], context: { service: service, operation: operation, status_code: status_code } ) when 429 RateLimitError.new( , retry_after: response['Retry-After']&.to_i, limit: response['X-RateLimit-Limit']&.to_i, remaining: response['X-RateLimit-Remaining']&.to_i, context: { service: service, operation: operation } ) when 500..599 ServerError.new( , hint: body[:hint] || 'A server error occurred. Please retry your request.', code: body[:code] || "server_error_#{status_code}", status_code: status_code, request_id: request_id, context: { service: service, operation: operation } ) else Error.new( , hint: body[:hint], code: body[:code] || "http_#{status_code}", context: { service: service, operation: operation, status_code: status_code } ) end end |
.parse_response_body(response) ⇒ Object
484 485 486 487 488 |
# File 'lib/brainzlab/errors.rb', line 484 def parse_response_body(response) JSON.parse(response.body, symbolize_names: true) rescue JSON::ParserError, TypeError {} end |
.wrap(error, service:, operation:) ⇒ BrainzLab::Error
Wrap a standard error into a structured BrainzLab error.
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/brainzlab/errors.rb', line 361 def wrap(error, service:, operation:) case error when Net::OpenTimeout, Net::ReadTimeout, Timeout::Error TimeoutError.new( "#{service} #{operation} timed out: #{error.}", hint: 'Check your network connection or increase timeout settings.', code: "#{service.downcase}_timeout", context: { service: service, operation: operation } ) when Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ENETUNREACH ConnectionError.new( "Unable to connect to #{service}: #{error.}", hint: 'Check that the service is running and accessible.', code: "#{service.downcase}_connection_failed", context: { service: service, operation: operation } ) when SocketError ConnectionError.new( "DNS resolution failed for #{service}: #{error.}", hint: 'Check your network connection and DNS settings.', code: "#{service.downcase}_dns_error", context: { service: service, operation: operation } ) when JSON::ParserError ServerError.new( "Invalid response from #{service}: #{error.}", hint: 'The server returned an unexpected response format.', code: "#{service.downcase}_invalid_response", context: { service: service, operation: operation } ) when OpenSSL::SSL::SSLError ConnectionError.new( "SSL error connecting to #{service}: #{error.}", hint: 'Check SSL certificates and ensure the connection is secure.', code: "#{service.downcase}_ssl_error", context: { service: service, operation: operation } ) else Error.new( "#{service} #{operation} failed: #{error.}", hint: 'An unexpected error occurred. Check the logs for more details.', code: "#{service.downcase}_error", context: { service: service, operation: operation, original_error: error.class.name } ) end end |