The godot-torrent library implements a standardized error handling system that provides:
The TorrentError
class represents a single error with detailed information.
Key Properties:
code
: Integer error code (see error codes below)category
: Error category (session, torrent, network, storage, etc.)message
: Human-readable error descriptioncontext
: Additional context about where/when the error occurredis_error()
: Returns true if this represents an actual error (code != OK)is_recoverable()
: Returns true if the error can be recovered fromCreating Errors:
# Create from error code
var error = TorrentError.create(TorrentError.INVALID_TORRENT_FILE, "Custom message", "context")
# Create from libtorrent error
var error = TorrentError.from_libtorrent_error(error_code, error_message, "context")
# Convert to dictionary
var error_dict = error.to_dict()
print(error_dict) # { "code": 201, "category": "torrent", "message": "...", ... }
The TorrentResult
class is a wrapper for operations that can fail, similar to Rust’s Result<T, E>
type.
Key Methods:
is_ok()
: Returns true if the operation succeededis_error()
: Returns true if the operation failedget_value()
: Returns the success value (or null if error)get_error()
: Returns the TorrentError (or null if success)unwrap()
: Returns value or prints error to consoleunwrap_or(default)
: Returns value or default if errorUsage Pattern:
# Methods that can fail return TorrentResult
var result = some_operation_that_can_fail()
if result.is_ok():
var value = result.get_value()
print("Success: ", value)
else:
var error = result.get_error()
print("Error: ", error.get_message())
print("Category: ", error.get_category())
print("Recoverable: ", error.is_recoverable())
Errors are organized into categories for easier handling:
Category | Code Range | Description |
---|---|---|
NONE |
0 | No error (success) |
SESSION_ERROR |
100-199 | Session lifecycle and configuration errors |
TORRENT_ERROR |
200-299 | Torrent-specific errors |
NETWORK_ERROR |
300-399 | Network connectivity and timeout errors |
STORAGE_ERROR |
400-499 | File system and storage errors |
PARSE_ERROR |
500-599 | Data parsing and format errors |
VALIDATION_ERROR |
600-699 | Input validation errors |
TRACKER_ERROR |
700-799 | Tracker communication errors |
DHT_ERROR |
800-899 | DHT-related errors |
PEER_ERROR |
900-999 | Peer connection errors |
INTERNAL_ERROR |
1000+ | Internal library errors |
SESSION_NOT_RUNNING
(100): Attempted operation when session is not runningSESSION_ALREADY_RUNNING
(101): Attempted to start an already running sessionSESSION_START_FAILED
(102): Failed to initialize sessionSESSION_STOP_FAILED
(103): Failed to stop session cleanlyINVALID_TORRENT_HANDLE
(200): Torrent handle is invalid or expiredINVALID_TORRENT_FILE
(201): Torrent file is malformed or corruptINVALID_MAGNET_URI
(202): Magnet URI is malformedTORRENT_ADD_FAILED
(203): Failed to add torrent to sessionTORRENT_REMOVE_FAILED
(204): Failed to remove torrent from sessionTORRENT_NOT_FOUND
(205): Torrent not found in sessionINVALID_PATH
(400): Path is malformed or invalidPATH_NOT_FOUND
(401): Specified path does not existPERMISSION_DENIED
(402): Insufficient permissions for operationDISK_FULL
(403): Not enough disk spaceSTORAGE_MOVE_FAILED
(404): Failed to move torrent storageFILE_RENAME_FAILED
(405): Failed to rename fileINVALID_PARAMETER
(600): Invalid parameter valueEMPTY_SAVE_PATH
(601): Save path is empty or nullINVALID_PIECE_INDEX
(602): Piece index out of rangeINVALID_FILE_INDEX
(603): File index out of rangeINVALID_PRIORITY
(604): Priority value out of valid rangeINVALID_URL
(605): URL is malformedvar session = TorrentSession.new()
var success = session.start_session()
if not success:
# Handle error - check Godot console for detailed message
print("Failed to start session")
return
Operations that can fail will log errors to the Godot console via push_error()
:
var handle = session.add_torrent_file(torrent_data, save_path)
if handle == null or not handle.is_valid():
# Error occurred - check console for details
print("Failed to add torrent")
return
Always validate inputs before calling library methods:
# Bad - will cause error
var handle = session.add_torrent_file(data, "") # Empty path
# Good - validate first
if save_path.is_empty():
print("Error: Save path cannot be empty")
return
var handle = session.add_torrent_file(data, save_path)
if not session.is_running():
print("Session not running - start it first")
session.start_session()
if not handle.is_valid():
print("Handle is invalid - cannot perform operation")
return
handle.pause() # Safe to use
All errors are reported to the Godot console using push_error()
with a standardized format:
[ClassName::method_name] Error message
Examples:
[TorrentSession::add_torrent_file] Session not running
[TorrentSession::add_torrent_file] Save path cannot be empty
[TorrentSession::add_torrent_file] libtorrent error 123: invalid torrent file
[TorrentHandle::pause] Invalid handle
[TorrentHandle::set_piece_priority] Exception: out of range
Libtorrent errors are automatically mapped to godot-torrent error codes:
Libtorrent Error | Mapped Code | Category |
---|---|---|
Invalid torrent file | INVALID_TORRENT_FILE |
TORRENT_ERROR |
Invalid magnet | INVALID_MAGNET_URI |
TORRENT_ERROR |
Permission denied | PERMISSION_DENIED |
STORAGE_ERROR |
Disk full | DISK_FULL |
STORAGE_ERROR |
Timeout | TIMEOUT |
NETWORK_ERROR |
Tracker error | TRACKER_ANNOUNCE_FAILED |
TRACKER_ERROR |
Connection failed | CONNECTION_FAILED |
NETWORK_ERROR |
These errors can typically be retried or worked around:
Strategy: Retry with backoff, try alternative trackers, or continue without that resource.
These errors require user intervention:
Strategy: Report error to user, log details, and request corrective action.
extends Node
var session: TorrentSession
var handle: TorrentHandle
func _ready():
session = TorrentSession.new()
# Start session with error checking
if not session.start_session():
push_error("Failed to start torrent session")
return
# Load torrent file
var file = FileAccess.open("res://test.torrent", FileAccess.READ)
if file == null:
push_error("Failed to open torrent file")
session.stop_session()
return
var torrent_data = file.get_buffer(file.get_length())
file.close()
# Add torrent with validation
var save_path = "downloads"
if save_path.is_empty():
push_error("Save path is empty")
session.stop_session()
return
handle = session.add_torrent_file(torrent_data, save_path)
if handle == null or not handle.is_valid():
push_error("Failed to add torrent - check console for details")
session.stop_session()
return
print("Torrent added successfully: ", handle.get_name())
func _exit_tree():
if session != null:
session.stop_session()
Planned improvements to the error handling system:
The standardized error handling system provides:
push_error()
Always check return values, validate inputs, and monitor the Godot console for detailed error information.