BareGit
"""Typed errors shared by the Firefox MCP server."""

from __future__ import annotations


class FirefoxMcpError(Exception):
    """Base class for errors safe to expose as MCP tool failures."""

    code = "internal_error"
    retryable = False

    def __init__(
        self,
        message: str,
        *,
        retryable: bool | None = None,
        details: dict[str, object] | None = None,
    ) -> None:
        super().__init__(message)
        self.message = message
        self.retryable = (
            type(self).retryable if retryable is None else retryable
        )
        self.details = details or {}


class ConfigurationError(FirefoxMcpError):
    """Report an invalid startup configuration."""

    code = "configuration_error"


class NotConnectedError(FirefoxMcpError):
    """Report that the configured Firefox RDP endpoint is unavailable."""

    code = "not_connected"
    retryable = True


class ConnectionLostError(FirefoxMcpError):
    """Report that an established RDP connection was lost."""

    code = "connection_lost"
    retryable = True


class RdpTimeoutError(FirefoxMcpError):
    """Report an RDP operation that exceeded its deadline."""

    code = "rdp_timeout"
    retryable = True


class RdpProtocolError(FirefoxMcpError):
    """Report an invalid or unexpected RDP packet."""

    code = "rdp_protocol_error"


class NoTabSelectedError(FirefoxMcpError):
    """Report that a page operation has no selected browser tab."""

    code = "no_tab_selected"
    retryable = True


class TabNotFoundError(FirefoxMcpError):
    """Report that a requested tab no longer exists."""

    code = "tab_not_found"
    retryable = True


class TargetReplacedError(FirefoxMcpError):
    """Report that navigation replaced the selected target actor."""

    code = "target_replaced"
    retryable = True


class ElementNotFoundError(FirefoxMcpError):
    """Report that a stored selector no longer resolves."""

    code = "element_not_found"
    retryable = True


class StaleElementError(FirefoxMcpError):
    """Report that a reference no longer identifies its snapshot element."""

    code = "stale_element"
    retryable = True


class ElementNotInteractableError(FirefoxMcpError):
    """Report an element that cannot perform the requested interaction."""

    code = "element_not_interactable"


class InvalidSelectorError(FirefoxMcpError):
    """Report invalid CSS selector syntax."""

    code = "invalid_selector"


class UnsupportedElementError(FirefoxMcpError):
    """Report an element type unsupported by an interaction tool."""

    code = "unsupported_element"


class NavigationTimeoutError(FirefoxMcpError):
    """Report a page that did not reach requested readiness in time."""

    code = "navigation_timeout"
    retryable = True


class WaitTimeoutError(FirefoxMcpError):
    """Report an observable page condition that did not become true."""

    code = "wait_timeout"
    retryable = True


class UploadFileInvalidError(FirefoxMcpError):
    """Report a local upload path that is not a readable regular file."""

    code = "upload_file_invalid"


class UploadTooLargeError(FirefoxMcpError):
    """Report an upload that exceeds configured byte limits."""

    code = "upload_too_large"


class UploadTargetInvalidError(FirefoxMcpError):
    """Report a target that is not a usable file input."""

    code = "upload_target_invalid"
    retryable = True


class UploadTransferError(FirefoxMcpError):
    """Report failure while transferring file chunks to the page."""

    code = "upload_transfer_failed"
    retryable = True


class UploadAssignmentError(FirefoxMcpError):
    """Report failure while assigning staged files to an input."""

    code = "upload_assignment_failed"
    retryable = True


class PageScriptError(FirefoxMcpError):
    """Report an unexpected exception in evaluated page JavaScript."""

    code = "page_script_failed"


class JavaScriptError(FirefoxMcpError):
    """Report an exception thrown by caller-supplied JavaScript."""

    code = "javascript_error"


class CancelledError(FirefoxMcpError):
    """Report cooperative cancellation of a browser operation."""

    code = "cancelled"
    retryable = True