Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: BatchResponseSortError internal exception #205

Merged
merged 1 commit into from
Aug 27, 2024
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
12 changes: 10 additions & 2 deletions dank_mids/_exceptions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@

import logging
import re
from typing import TYPE_CHECKING, Union
from typing import TYPE_CHECKING, List, Union

from aiohttp.client_exceptions import ClientResponseError

if TYPE_CHECKING:
from dank_mids.types import PartialRequest, PartialResponse
from dank_mids._requests import RPCRequest
from dank_mids.types import PartialRequest, PartialResponse, RawResponse, Response


logger = logging.getLogger("dank_mids.exceptions")
Expand Down Expand Up @@ -50,3 +51,10 @@ def __init__(self, e: Union[ValueError, internal_err_types]) -> None:
logger.warning(f"unhandled exception inside dank mids internals: {e}", exc_info=True)
self._original_exception = e
super().__init__(e.__repr__())

class BatchResponseSortError(Exception):
"""A `BatchResponseSortError` indicates your rpc needs some special handling to properly handle batch calls / responses."""
def __init__(self, calls: List["RPCRequest"], response: List["RawResponse"]) -> None:
self.calls = calls
self.results = [raw.decode() for raw in response]
super().__init__([call.uid for call in calls], self.results)
11 changes: 6 additions & 5 deletions dank_mids/_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
from dank_mids import ENVIRONMENT_VARIABLES as ENVS
from dank_mids import _debugging, constants, stats
from dank_mids._demo_mode import demo_logger
from dank_mids._exceptions import (BadResponse, DankMidsClientResponseError,
DankMidsInternalError, EmptyBatch,
ExceedsMaxBatchSize, PayloadTooLarge,
from dank_mids._exceptions import (BadResponse, BatchResponseSortError,
DankMidsClientResponseError, DankMidsInternalError,
EmptyBatch, ExceedsMaxBatchSize, PayloadTooLarge,
ResponseNotReady, internal_err_types)
from dank_mids._uid import _AlertingRLock
from dank_mids.helpers import _codec, _session
Expand Down Expand Up @@ -814,10 +814,11 @@ async def spoof_response(self, response: List[RawResponse], calls: List[RPCReque
# NOTE: these providers don't always return batch results in the correct ordering
# NOTE: is it maybe because they
calls = sorted(calls, key=lambda call: call.uid)
for i, (call, raw) in enumerate(zip(calls, response)):
for call, raw in zip(calls, response):
# TODO: make sure this doesn't ever raise and then delete it
decoded = raw.decode()
assert call.uid == decoded.id, (i, call, decoded, response, [[call.uid for call in calls], [raw.decode() for raw in response]])
if call.uid != decoded.id:
raise BatchResponseSortError(calls, response)

for r in await asyncio.gather(*[call.spoof_response(raw) for call, raw in zip(calls, response)], return_exceptions=True):
# NOTE: By doing this with the exceptions we allow any successful calls to get their results sooner
Expand Down
Loading