Skip to content

Commit 05e3bd6

Browse files
committed
more generic error handling
1 parent 01f05e7 commit 05e3bd6

File tree

4 files changed

+45
-56
lines changed

4 files changed

+45
-56
lines changed

livekit-api/livekit/api/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636

3737
from .twirp_client import TwirpError, TwirpErrorCode
3838
from .livekit_api import LiveKitAPI
39-
from .sip_service import SIPError
4039
from .access_token import VideoGrants, SIPGrants, AccessToken, TokenVerifier
4140
from .webhook import WebhookReceiver
4241
from .version import __version__
@@ -55,5 +54,4 @@
5554
"WebhookReceiver",
5655
"TwirpError",
5756
"TwirpErrorCode",
58-
"SIPError",
5957
]

livekit-api/livekit/api/livekit_api.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ def __init__(
5050
if not api_key or not api_secret:
5151
raise ValueError("api_key and api_secret must be set")
5252

53-
if not timeout:
54-
timeout = aiohttp.ClientTimeout(total=60)
55-
56-
self._custom_session = True if session is None else False
57-
self._session = session or aiohttp.ClientSession(timeout=timeout)
53+
self._custom_session = True
54+
self._session = session
55+
if not self._session:
56+
self._custom_session = False
57+
if not timeout:
58+
timeout = aiohttp.ClientTimeout(total=60)
59+
self._session = aiohttp.ClientSession(timeout=timeout)
5860

5961
self._room = RoomService(self._session, url, api_key, api_secret)
6062
self._ingress = IngressService(self._session, url, api_key, api_secret)

livekit-api/livekit/api/sip_service.py

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import aiohttp
2-
import re
32
from typing import Optional
43

54
from livekit.protocol.models import ListUpdate
@@ -32,46 +31,11 @@
3231
SIPTransport,
3332
)
3433
from ._service import Service
35-
from .twirp_client import TwirpError
3634
from .access_token import VideoGrants, SIPGrants
3735

3836
SVC = "SIP"
3937
"""@private"""
4038

41-
_sip_status_pattern = re.compile(r"sip status: (\d+) \((.*?)\)")
42-
43-
44-
class SIPError(TwirpError):
45-
"""Error raised by SIP service operations.
46-
47-
Contains SIP specific status and message information when available.
48-
"""
49-
50-
def __init__(self, code: str, msg: str, status: Optional[int] = None):
51-
super().__init__(code, msg, status=status)
52-
self._sip_status: Optional[int] = None
53-
self._sip_message: Optional[str] = None
54-
55-
@classmethod
56-
def from_twirp_error(cls, e: TwirpError) -> "SIPError":
57-
err = cls(e.code, e.message, status=e.status)
58-
# Parse SIP status and message from error message
59-
sip_status_match = _sip_status_pattern.search(e.message)
60-
if sip_status_match:
61-
err._sip_status = int(sip_status_match.group(1))
62-
err._sip_message = sip_status_match.group(2)
63-
# maintain traceback from the original error
64-
err.__traceback__ = e.__traceback__
65-
return err
66-
67-
@property
68-
def sip_status(self) -> Optional[int]:
69-
return self._sip_status
70-
71-
@property
72-
def sip_message(self) -> Optional[str]:
73-
return self._sip_message
74-
7539

7640
class SipService(Service):
7741
"""Client for LiveKit SIP Service API
@@ -445,17 +409,14 @@ async def create_sip_participant(
445409
):
446410
client_timeout = aiohttp.ClientTimeout(total=20)
447411

448-
try:
449-
return await self._client.request(
450-
SVC,
451-
"CreateSIPParticipant",
452-
create,
453-
self._admin_headers(),
454-
SIPParticipantInfo,
455-
timeout=client_timeout,
456-
)
457-
except TwirpError as e:
458-
raise SIPError.from_twirp_error(e) from None
412+
return await self._client.request(
413+
SVC,
414+
"CreateSIPParticipant",
415+
create,
416+
self._auth_header(VideoGrants(), sip=SIPGrants(call=True)),
417+
SIPParticipantInfo,
418+
timeout=client_timeout,
419+
)
459420

460421
async def transfer_sip_participant(
461422
self, transfer: TransferSIPParticipantRequest

livekit-api/livekit/api/twirp_client.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,18 @@
2222

2323

2424
class TwirpError(Exception):
25-
def __init__(self, code: str, msg: str, *, status: Optional[int] = None) -> None:
25+
def __init__(
26+
self,
27+
code: str,
28+
msg: str,
29+
*,
30+
status: Optional[int] = None,
31+
metadata: Optional[Dict[str, str]] = None,
32+
) -> None:
2633
self._code = code
2734
self._msg = msg
2835
self._status = status
36+
self._metadata = metadata or {}
2937

3038
@property
3139
def code(self) -> str:
@@ -37,8 +45,23 @@ def message(self) -> str:
3745

3846
@property
3947
def status(self) -> Optional[int]:
48+
"""HTTP status code"""
4049
return self._status
4150

51+
@property
52+
def metadata(self) -> Dict[str, str]:
53+
"""Twirp metadata"""
54+
return self._metadata
55+
56+
def __str__(self) -> str:
57+
result = f"TwirpError(code={self.code}, message={self.message}"
58+
if self.status is not None:
59+
result += f", status={self.status}"
60+
if self.metadata:
61+
result += f", metadata={self.metadata}"
62+
result += ")"
63+
return result
64+
4265

4366
class TwirpErrorCode:
4467
CANCELED = "canceled"
@@ -106,4 +129,9 @@ async def request(
106129
# when we have an error, Twirp always encode it in json
107130
error_data = await resp.json()
108131
print(f"Error: {error_data}, headers: {resp.headers}")
109-
raise TwirpError(error_data["code"], error_data["msg"], status=resp.status)
132+
raise TwirpError(
133+
error_data.get("code", "unknown"),
134+
error_data.get("msg", ""),
135+
status=resp.status,
136+
metadata=error_data.get("meta"),
137+
)

0 commit comments

Comments
 (0)