Files
kamidso-back/kamidso/native_connectors/errors.py
T
javadandCursor edbaa2acec Add native Didar connectors so chats can query CRM data reliably.
Connector calls, semantic rules, and DuckDB memory keep long runs stable, and stream retry stops chats from stalling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-12 19:26:47 +03:30

145 lines
3.7 KiB
Python

"""Error taxonomy for native connector calls."""
from __future__ import annotations
from typing import Any, Dict, List, Optional
class NativeConnectorError(Exception):
error_type = "connector_error"
http_sent = False
def __init__(
self,
message: str,
*,
function: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
) -> None:
super().__init__(message)
self.message = message
self.function = function
self.details = details or {}
def to_payload(self) -> Dict[str, Any]:
payload: Dict[str, Any] = {
"ok": False,
"error_type": self.error_type,
"message": self.message,
"http_sent": self.http_sent,
}
if self.function:
payload["function"] = self.function
payload.update(self.details)
return payload
class CatalogError(NativeConnectorError):
error_type = "catalog_error"
class ConnectorNotAttached(NativeConnectorError):
error_type = "connector_not_attached"
class ConnectorNotFound(NativeConnectorError):
error_type = "connector_not_found"
class ConnectorAmbiguous(NativeConnectorError):
error_type = "connector_ambiguous"
def __init__(self, names: List[str]) -> None:
listing = "\n".join(f"- {name}" for name in names)
super().__init__(
"Several native connectors are attached.\n\nSpecify connection:\n" + listing,
details={"connections": names},
)
class ProviderNotFound(NativeConnectorError):
error_type = "provider_not_found"
class FunctionNotFound(NativeConnectorError):
error_type = "unknown_function"
def __init__(self, function: str, provider_label: str, suggestions: List[str]) -> None:
super().__init__(
f"Function '{function}' does not exist for {provider_label}.",
function=function,
details={
"suggestions": suggestions,
"instruction": "Use only predefined function names.",
},
)
class FunctionDisabled(NativeConnectorError):
error_type = "function_disabled"
class OperationNotAllowed(NativeConnectorError):
error_type = "operation_not_allowed"
def __init__(self, function: str, effect: str) -> None:
super().__init__(
"This connector is read-only. No HTTP request was sent.",
function=function,
details={"effect": effect},
)
class ValidationFailed(NativeConnectorError):
error_type = "validation_error"
class AuthenticationFailed(NativeConnectorError):
"""Local credential failure. Remote 401 uses RemoteCallFailed."""
error_type = "authentication_error"
class RemoteCallFailed(NativeConnectorError):
def __init__(
self,
message: str,
*,
error_type: str,
function: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
) -> None:
super().__init__(message, function=function, details=details)
self.error_type = error_type
self.http_sent = True
class TransportFailed(NativeConnectorError):
error_type = "transport_error"
class CallTimeout(NativeConnectorError):
error_type = "timeout_error"
class ResponseTooLarge(NativeConnectorError):
error_type = "response_too_large"
http_sent = True
class InvalidJSONResponse(NativeConnectorError):
error_type = "invalid_json_response"
http_sent = True
class ResultMaterializationError(NativeConnectorError):
error_type = "result_materialization_error"
http_sent = True
class AccuracyGuard(NativeConnectorError):
"""An exact management figure cannot be verified. No substitute total is included."""
error_type = "accuracy_guard"
http_sent = True