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

chore(isolate): separate serialization and deserialization exceptions #129

Merged
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
43 changes: 26 additions & 17 deletions src/isolate/connections/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import importlib
import os
from contextlib import contextmanager
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Iterator, cast
from typing import TYPE_CHECKING, Any, cast

from tblib import Traceback, TracebackParseError

Expand All @@ -23,23 +22,18 @@ def dumps(self, obj: Any) -> bytes: ...


@dataclass
class SerializationError(IsolateException):
class BaseSerializationError(IsolateException):
"""An error that happened during the serialization process."""

message: str


@contextmanager
def _step(message: str) -> Iterator[None]:
"""A context manager to capture every expression
underneath it and if any of them fails for any reason
then it will raise a SerializationError with the
given message."""
class SerializationError(BaseSerializationError):
pass

try:
yield
except BaseException as exception:
raise SerializationError("Error while " + message) from exception

class DeserializationError(BaseSerializationError):
pass


def as_serialization_method(backend: Any) -> SerializationBackend:
Expand Down Expand Up @@ -68,13 +62,22 @@ def load_serialized_object(
flag is set to true, then the given object will be raised as an exception (instead
of being returned)."""

with _step(f"preparing the serialization backend ({serialization_method})"):
try:
serialization_backend = as_serialization_method(
importlib.import_module(serialization_method)
)
except BaseException as exc:
raise DeserializationError(
"Error while preparing the serialization backend "
f"({serialization_method})"
) from exc

with _step("deserializing the given object"):
try:
result = serialization_backend.loads(raw_object)
except BaseException as exc:
raise DeserializationError(
"Error while deserializing the given object"
) from exc

if was_it_raised:
raise prepare_exc(result, stringized_traceback=stringized_traceback)
Expand All @@ -86,13 +89,19 @@ def serialize_object(serialization_method: str, object: Any) -> bytes:
"""Serialize the given object using the given serialization method. If
anything fails, then a SerializationError will be raised."""

with _step(f"preparing the serialization backend ({serialization_method})"):
try:
serialization_backend = as_serialization_method(
importlib.import_module(serialization_method)
)
except BaseException as exc:
raise SerializationError(
f"Error while preparing the serialization backend ({serialization_method})"
) from exc

with _step("serializing the given object"):
try:
return serialization_backend.dumps(object)
except BaseException as exc:
raise SerializationError("Error while serializing the given object") from exc


def is_agent() -> bool:
Expand Down
Loading