Module: Daytona::Sdk
- Defined in:
- lib/daytona/sdk/errors.rb,
lib/daytona/sdk.rb,
lib/daytona/sdk/version.rb,
lib/daytona/sdk/deprecated.rb,
lib/daytona/sdk/file_download_patch.rb,
sig/daytona/sdk.rbs
Overview
rubocop:disable Metrics/ModuleLength
Defined Under Namespace
Modules: FileDownloadPatch Classes: A11yUnavailableError, AuthenticationError, BadGatewayError, BadRequestError, CommandAlreadyCompletedError, ConflictError, ConnectionError, ConnectionTimeoutError, Error, FileAccessDeniedError, FileNotFoundError, FileReadFailedError, ForbiddenError, GitAuthFailedError, GitBranchExistsError, GitBranchNotFoundError, GitDirtyWorktreeError, GitMergeConflictError, GitPushRejectedError, GitRepoNotFoundError, GoneError, InternalServerError, InvalidFilePathError, LspServerNotInitializedError, NotFoundError, ProcessExecutionTimeoutError, ProcessNotFoundError, RateLimitError, RecordingFfmpegNotFoundError, RecordingStillActiveError, ServerError, ServiceUnavailableError, SessionEndedError, TimeoutError, UnprocessableEntityError
Constant Summary collapse
- API_ERROR_CLASSES =
ApiError classes raised by the generated OpenAPI clients. Kept here so the error module can resolve them without depending on
sdk.rb. [DaytonaApiClient::ApiError, DaytonaToolboxApiClient::ApiError].freeze
- SOURCE_API =
Wire-format
sourcevalues set by the translation layer when a Daytona service stamps them on the wire envelope.nilsource means the response did not carry a structured envelope (treat as opaque). 'DAYTONA_API'- SOURCE_DAEMON =
'DAYTONA_DAEMON'- SOURCE_PROXY =
'DAYTONA_PROXY'- STATUS_CODE_TO_ERROR =
Routing tables
{ 400 => BadRequestError, 401 => AuthenticationError, 403 => ForbiddenError, 404 => NotFoundError, 408 => TimeoutError, 409 => ConflictError, 410 => GoneError, 422 => UnprocessableEntityError, 429 => RateLimitError, 500 => InternalServerError, 502 => BadGatewayError, 503 => ServiceUnavailableError, 504 => TimeoutError }.freeze
- CODE_TO_ERROR =
(source, code) tuple → exception class. Resolved BEFORE the status code, so a server-stamped domain code always wins over the generic status class.
{ # Daemon: git [SOURCE_DAEMON, 'GIT_AUTH_FAILED'] => GitAuthFailedError, [SOURCE_DAEMON, 'GIT_REPO_NOT_FOUND'] => GitRepoNotFoundError, [SOURCE_DAEMON, 'GIT_BRANCH_NOT_FOUND'] => GitBranchNotFoundError, [SOURCE_DAEMON, 'GIT_BRANCH_EXISTS'] => GitBranchExistsError, [SOURCE_DAEMON, 'GIT_PUSH_REJECTED'] => GitPushRejectedError, [SOURCE_DAEMON, 'GIT_DIRTY_WORKTREE'] => GitDirtyWorktreeError, [SOURCE_DAEMON, 'GIT_MERGE_CONFLICT'] => GitMergeConflictError, # Daemon: filesystem [SOURCE_DAEMON, 'FILE_NOT_FOUND'] => FileNotFoundError, [SOURCE_DAEMON, 'FILE_ACCESS_DENIED'] => FileAccessDeniedError, [SOURCE_DAEMON, 'INVALID_FILE_PATH'] => InvalidFilePathError, [SOURCE_DAEMON, 'FILE_READ_FAILED'] => FileReadFailedError, # Daemon: LSP [SOURCE_DAEMON, 'LSP_SERVER_NOT_INITIALIZED'] => LspServerNotInitializedError, # Daemon: process / session [SOURCE_DAEMON, 'PROCESS_EXECUTION_TIMEOUT'] => ProcessExecutionTimeoutError, [SOURCE_DAEMON, 'PROCESS_NOT_FOUND'] => ProcessNotFoundError, [SOURCE_DAEMON, 'SESSION_ENDED'] => SessionEndedError, [SOURCE_DAEMON, 'COMMAND_ALREADY_COMPLETED'] => CommandAlreadyCompletedError, # Daemon: computer-use [SOURCE_DAEMON, 'A11Y_UNAVAILABLE'] => A11yUnavailableError, [SOURCE_DAEMON, 'RECORDING_STILL_ACTIVE'] => RecordingStillActiveError, [SOURCE_DAEMON, 'RECORDING_FFMPEG_NOT_FOUND'] => RecordingFfmpegNotFoundError }.freeze
- VERSION =
'0.203.0'- ValidationError =
Deprecated.
Use BadRequestError instead. Kept as an alias so existing
rescue Daytona::Sdk::ValidationErrorblocks keep working. BadRequestError
Class Method Summary collapse
-
.api_error_details(error) ⇒ Object
Extract status code, code, source and headers from a raised OpenAPI error.
-
.logger ⇒ Object
The error hierarchy and translation helpers live in
sdk/errors.rb. -
.wrap_error(error, prefix = nil) ⇒ Object
Translate an OpenAPI-client error into the most specific Daytona SDK exception.
Class Method Details
.api_error_details(error) ⇒ Object
Extract status code, code, source and headers from a raised OpenAPI error. Returns an empty hash when the error is not one of the generated client types.
228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/daytona/sdk/errors.rb', line 228 def self.api_error_details(error) return {} unless API_ERROR_CLASSES.any? { |c| error.is_a?(c) } data = parse_error_body(error.respond_to?(:response_body) ? error.response_body : nil) { status_code: error.respond_to?(:code) ? error.code : nil, code: data[:code], source: data[:source], headers: error.respond_to?(:response_headers) ? error.response_headers : nil } end |
.logger ⇒ Object
The error hierarchy and translation helpers live in sdk/errors.rb.
This file just provides cross-cutting bits that need to be loaded
alongside them.
58 |
# File 'lib/daytona/sdk.rb', line 58 def self.logger = @logger ||= Logger.new($stdout, level: Logger::INFO) |
.wrap_error(error, prefix = nil) ⇒ Object
Translate an OpenAPI-client error into the most specific Daytona SDK
exception. Accepts an optional prefix that's prepended to the
message for context (e.g. "Failed to create sandbox"). When error
is already an Sdk::Error (e.g. raised by the streaming transfer
helpers for cancel/timeout), its class is preserved and only the
message is prefixed.
212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/daytona/sdk/errors.rb', line 212 def self.wrap_error(error, prefix = nil) if error.is_a?(Error) = prefix ? "#{prefix}: #{error.}" : error. return error.class.new(, status_code: error.status_code, code: error.code, source: error.source, headers: error.headers) end details = api_error_details(error) = (error) || error. = prefix ? "#{prefix}: #{}" : error_class_for(details).new(, **details.slice(:status_code, :code, :source, :headers)) end |