Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/polymarket/_internal/rfq.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,9 @@ def _handle_rfq_error(self, raw: dict[str, object]) -> None:
request_type = raw.get("request_type")
rfq_id = raw.get("rfq_id")
quote_id = raw.get("quote_id")
error_id = raw.get("error_id")
if error_id is not None and not isinstance(error_id, str):
raise UnexpectedResponseError("Expected RFQ error_id to be a string.")
code = _parse_error_code(raw.get("code"))
message = raw.get("error")
text = message if isinstance(message, str) else "RFQ request failed."
Expand All @@ -459,7 +462,7 @@ def _handle_rfq_error(self, raw: dict[str, object]) -> None:
raise TransportError("Uncorrelated RFQ quoter error.")
self._reject(
_quote_ack_key(rfq_id),
RfqQuoteRejectedError(text, rfq_id=rfq_id, code=code),
RfqQuoteRejectedError(text, rfq_id=rfq_id, code=code, error_id=error_id),
)
elif request_type == "RFQ_QUOTE_CANCEL":
if not isinstance(rfq_id, str) or not isinstance(quote_id, str):
Expand All @@ -471,6 +474,7 @@ def _handle_rfq_error(self, raw: dict[str, object]) -> None:
rfq_id=rfq_id,
quote_id=quote_id,
code=code,
error_id=error_id,
),
)
elif request_type == "RFQ_CONFIRMATION_RESPONSE":
Expand All @@ -483,6 +487,7 @@ def _handle_rfq_error(self, raw: dict[str, object]) -> None:
rfq_id=rfq_id,
quote_id=quote_id,
code=code,
error_id=error_id,
),
)

Expand Down
16 changes: 15 additions & 1 deletion src/polymarket/rfq.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class RfqErrorCode(StrEnum):
INVALID_RFQ = "INVALID_RFQ"
INVALID_RFQ_STATE = "INVALID_RFQ_STATE"
INVALID_ROLE = "INVALID_ROLE"
INVALID_SIGNATURE = "INVALID_SIGNATURE"
INTERNAL_ERROR = "INTERNAL_ERROR"
LEG_METADATA_UNAVAILABLE = "LEG_METADATA_UNAVAILABLE"
MAKER_ALREADY_RESPONDED = "MAKER_ALREADY_RESPONDED"
MAKER_NOT_REQUIRED = "MAKER_NOT_REQUIRED"
Expand Down Expand Up @@ -170,10 +172,18 @@ async def decline(self) -> RfqConfirmationAck:


class RfqQuoteRejectedError(PolymarketError):
def __init__(self, message: str, *, rfq_id: RfqId, code: RfqErrorCode | None = None) -> None:
def __init__(
self,
message: str,
*,
rfq_id: RfqId,
code: RfqErrorCode | None = None,
error_id: str | None = None,
) -> None:
super().__init__(message)
self.rfq_id = rfq_id
self.code = code
self.error_id = error_id


class RfqCancelQuoteRejectedError(PolymarketError):
Expand All @@ -184,11 +194,13 @@ def __init__(
rfq_id: RfqId,
quote_id: RfqQuoteId,
code: RfqErrorCode | None = None,
error_id: str | None = None,
) -> None:
super().__init__(message)
self.rfq_id = rfq_id
self.quote_id = quote_id
self.code = code
self.error_id = error_id


class RfqConfirmationRejectedError(PolymarketError):
Expand All @@ -199,11 +211,13 @@ def __init__(
rfq_id: RfqId,
quote_id: RfqQuoteId,
code: RfqErrorCode | None = None,
error_id: str | None = None,
) -> None:
super().__init__(message)
self.rfq_id = rfq_id
self.quote_id = quote_id
self.code = code
self.error_id = error_id


@runtime_checkable
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/test_rfq.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ async def handler(ws: ServerConnection) -> None:
{
"type": "RFQ_ERROR",
"request_type": "RFQ_QUOTE",
"error_id": "reqerr-1",
"rfq_id": RFQ_ID,
"code": code,
"error": "quote rejected",
Expand All @@ -406,6 +407,7 @@ async def handler(ws: ServerConnection) -> None:
with pytest.raises(RfqQuoteRejectedError, match="quote rejected") as exc_info:
await event.quote(price=Decimal("0.45"))
assert exc_info.value.code == code
assert exc_info.value.error_id == "reqerr-1"
break


Expand Down
Loading