mirror of
https://github.com/katanemo/plano.git
synced 2026-07-05 15:52:12 +02:00
Add error handling for OTLP/gRPC listener binding in trace command (#748)
This commit is contained in:
parent
1df43872a6
commit
ef285f1213
2 changed files with 68 additions and 2 deletions
|
|
@ -28,6 +28,17 @@ MAX_TRACES = 50
|
||||||
MAX_SPANS_PER_TRACE = 500
|
MAX_SPANS_PER_TRACE = 500
|
||||||
|
|
||||||
|
|
||||||
|
class TraceListenerBindError(RuntimeError):
|
||||||
|
"""Raised when the OTLP/gRPC listener cannot bind to the requested address."""
|
||||||
|
|
||||||
|
|
||||||
|
def _trace_listener_bind_error_message(address: str) -> str:
|
||||||
|
return (
|
||||||
|
f"Failed to start OTLP listener on {address}: address is already in use.\n"
|
||||||
|
"Stop the process using that port or run `planoai trace listen --port <PORT>`."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class TraceSummary:
|
class TraceSummary:
|
||||||
trace_id: str
|
trace_id: str
|
||||||
|
|
@ -501,7 +512,15 @@ def _create_trace_server(host: str, grpc_port: int) -> grpc.Server:
|
||||||
trace_service_pb2_grpc.add_TraceServiceServicer_to_server(
|
trace_service_pb2_grpc.add_TraceServiceServicer_to_server(
|
||||||
_OTLPTraceServicer(), grpc_server
|
_OTLPTraceServicer(), grpc_server
|
||||||
)
|
)
|
||||||
grpc_server.add_insecure_port(f"{host}:{grpc_port}")
|
address = f"{host}:{grpc_port}"
|
||||||
|
try:
|
||||||
|
bound_port = grpc_server.add_insecure_port(address)
|
||||||
|
except RuntimeError as exc:
|
||||||
|
raise TraceListenerBindError(
|
||||||
|
_trace_listener_bind_error_message(address)
|
||||||
|
) from exc
|
||||||
|
if bound_port == 0:
|
||||||
|
raise TraceListenerBindError(_trace_listener_bind_error_message(address))
|
||||||
grpc_server.start()
|
grpc_server.start()
|
||||||
return grpc_server
|
return grpc_server
|
||||||
|
|
||||||
|
|
@ -509,7 +528,10 @@ def _create_trace_server(host: str, grpc_port: int) -> grpc.Server:
|
||||||
def _start_trace_listener(host: str, grpc_port: int) -> None:
|
def _start_trace_listener(host: str, grpc_port: int) -> None:
|
||||||
"""Start the OTLP/gRPC listener and block until interrupted."""
|
"""Start the OTLP/gRPC listener and block until interrupted."""
|
||||||
console = Console()
|
console = Console()
|
||||||
grpc_server = _create_trace_server(host, grpc_port)
|
try:
|
||||||
|
grpc_server = _create_trace_server(host, grpc_port)
|
||||||
|
except TraceListenerBindError as exc:
|
||||||
|
raise click.ClickException(str(exc)) from exc
|
||||||
|
|
||||||
console.print()
|
console.print()
|
||||||
console.print(f"[bold {PLANO_COLOR}]Listening for traces...[/bold {PLANO_COLOR}]")
|
console.print(f"[bold {PLANO_COLOR}]Listening for traces...[/bold {PLANO_COLOR}]")
|
||||||
|
|
|
||||||
44
cli/test/test_trace_cmd.py
Normal file
44
cli/test/test_trace_cmd.py
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import pytest
|
||||||
|
import rich_click as click
|
||||||
|
|
||||||
|
from planoai import trace_cmd
|
||||||
|
|
||||||
|
|
||||||
|
class _FakeGrpcServer:
|
||||||
|
def add_insecure_port(self, _address: str) -> int:
|
||||||
|
raise RuntimeError("bind failed")
|
||||||
|
|
||||||
|
def start(self) -> None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_trace_server_raises_bind_error(monkeypatch):
|
||||||
|
monkeypatch.setattr(
|
||||||
|
trace_cmd.grpc, "server", lambda *_args, **_kwargs: _FakeGrpcServer()
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
trace_cmd.trace_service_pb2_grpc,
|
||||||
|
"add_TraceServiceServicer_to_server",
|
||||||
|
lambda *_args, **_kwargs: None,
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(trace_cmd.TraceListenerBindError) as excinfo:
|
||||||
|
trace_cmd._create_trace_server("0.0.0.0", 4317)
|
||||||
|
|
||||||
|
assert "already in use" in str(excinfo.value)
|
||||||
|
assert "planoai trace listen --port" in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_start_trace_listener_converts_bind_error_to_click_exception(monkeypatch):
|
||||||
|
monkeypatch.setattr(
|
||||||
|
trace_cmd,
|
||||||
|
"_create_trace_server",
|
||||||
|
lambda *_args, **_kwargs: (_ for _ in ()).throw(
|
||||||
|
trace_cmd.TraceListenerBindError("port in use")
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(click.ClickException) as excinfo:
|
||||||
|
trace_cmd._start_trace_listener("0.0.0.0", 4317)
|
||||||
|
|
||||||
|
assert "port in use" in str(excinfo.value)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue