Skip to content

Conversation

@viren-nadkarni
Copy link
Member

@viren-nadkarni viren-nadkarni commented Sep 17, 2025

Changes

#13129 introduced a context manager for translating Moto exceptions into LS serialisable ones.

This PR integrates this mechanism with the handler chain itself and opts to remove the context manager. With this, the complexity and overhead of handling these cases is abstracted away from providers.

Tests

Unit tested. Integration tested by test_send_email_raises_message_rejected

Related

Supersedes: #13129

Closes: PNX-105

@viren-nadkarni viren-nadkarni self-assigned this Sep 17, 2025
@viren-nadkarni viren-nadkarni added semver: patch Non-breaking changes which can be included in patch releases docs: skip Pull request does not require documentation changes labels Sep 17, 2025
@github-actions
Copy link

github-actions bot commented Sep 17, 2025

Test Results - Preflight, Unit

22 298 tests  ±0   20 555 ✅ ±0   14m 4s ⏱️ - 2m 8s
     1 suites ±0    1 743 💤 ±0 
     1 files   ±0        0 ❌ ±0 

Results for commit 751aed4. ± Comparison against base commit 658d6fb.

This pull request removes 1 and adds 1 tests. Note that renamed tests count towards both.
tests.unit.test_moto ‑ test_service_exception_translator_context_manager
tests.unit.aws.handlers.test_service.TestServiceExceptionSerializer ‑ test_moto_exception_is_parsed

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Sep 17, 2025

Test Results (amd64) - Acceptance

7 tests  ±0   5 ✅ ±0   3m 20s ⏱️ -3s
1 suites ±0   2 💤 ±0 
1 files   ±0   0 ❌ ±0 

Results for commit 751aed4. ± Comparison against base commit 658d6fb.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Sep 17, 2025

Test Results (amd64) - Integration, Bootstrap

    5 files  ±0      5 suites  ±0   2h 38m 55s ⏱️ +28s
5 187 tests ±0  4 690 ✅ ±0  497 💤 ±0  0 ❌ ±0 
5 193 runs  ±0  4 690 ✅ ±0  503 💤 ±0  0 ❌ ±0 

Results for commit 751aed4. ± Comparison against base commit 658d6fb.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Sep 17, 2025

LocalStack Community integration with Pro

    2 files  ±0      2 suites  ±0   2h 1m 59s ⏱️ + 2m 31s
4 813 tests ±0  4 476 ✅ ±0  337 💤 ±0  0 ❌ ±0 
4 815 runs  ±0  4 476 ✅ ±0  339 💤 ±0  0 ❌ ±0 

Results for commit 751aed4. ± Comparison against base commit 658d6fb.

♻️ This comment has been updated with latest results.

@bentsku
Copy link
Contributor

bentsku commented Sep 18, 2025

The issue here is that the base runtime does not have the moto dependency, and the idea was to not have a moto dependency in our "core runtime" as part of the S3 image project.

Handling service exception in the skeleton.py seems to be a remnant of our previous architecture, and it might be better to catch them in an exception handler (see ServiceExceptionSerializer). I believe it is our plan to remove the exception handling from skeleton to move everything to ServiceExceptionSerializer.

I think the easiest way here would be to add an exception handler in handlers.serve_custom_exception_handlers which would handle this, and could be added only if moto is available?

@viren-nadkarni viren-nadkarni changed the title Integrate Moto exception translation into ASF Integrate Moto exception translation into handler chain Sep 24, 2025
@alexrashed alexrashed added the notes: skip Pull request does not have to be mentioned in the release notes label Sep 24, 2025
@viren-nadkarni
Copy link
Member Author

Thanks for the pointer @bentsku! I moved this into the exception handler in the chain and also accommodated for possible unavailability of Moto, although I'm not sure whether this is the cleanest approach.

@viren-nadkarni viren-nadkarni marked this pull request as ready for review September 25, 2025 07:22
Copy link
Member

@thrau thrau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! it's great to see that we now consider compatibility in environments where moto is not a dependency, like the s3 image.

i was wondering whether the cleaner approach would have been to write separate handlers for Moto exceptions, but only add those to the handler chain if moto is available, rather than conditionally inlining the moto exception handling as we do here. but ultimately i think it makes no difference, since all these handlers are hyper-specific to AWS anyway.

Comment on lines 28 to 32
self._moto_service_exception = types.EllipsisType
with contextlib.suppress(ModuleNotFoundError, AttributeError):
self._moto_service_exception = importlib.import_module(
"moto.core.exceptions"
).ServiceException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: i think i would prefer this, simply because the dynamic import via import_module makes it harder/impossible for an IDE to detect the import, whereas from moto.core.exceptions import ServiceException will show up in searches, module uses, etc.

        try:
            from moto.core.exceptions import ServiceException
            self._moto_service_exception = ServiceException
        except (ModuleNotFoundError, AttributeError):
            self._moto_service_exception = types.EllipsisType

Copy link
Contributor

@bentsku bentsku Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can even use the newer things, like it's done for the Moto patches conditionally applied for S3:

if find_spec("moto"):
    from moto.core.exceptions import ServiceException
    self._moto_service_exception = ServiceException
else:
    self._moto_service_exception = types.EllipsisType

It's the new advised way, except ModuleNotError might raise some linting warnings 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, changed in 751aed4 👍

Comment on lines 161 to 169
# Moto may not be available in stripped-down versions of LocalStack, like LocalStack S3 image.
self._moto_service_exception = types.EllipsisType
try:
self._moto_service_exception = importlib.import_module(
"moto.core.exceptions"
).ServiceException
except (ModuleNotFoundError, AttributeError) as exc:
LOG.debug("Unable to set up Moto ServiceException translation: %s", exc)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Copy link
Contributor

@bentsku bentsku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nothing much more to add than what @thrau as said 👍 I also think the conditionally added handlers might be a bit cleaner and decoupled, but now that I think of it a bit more, it won't update exception parameter itself of the ServiceExceptionSerializer, so we'd probably need additional work (attach it to the context as service_exception) and verify if there is something attached before doing the isinstance call on the exception parameter.

I think this will work nicely 👍 thanks for tackling this!

@alexrashed alexrashed added this to the 4.9 milestone Sep 26, 2025
@viren-nadkarni viren-nadkarni modified the milestones: 4.9, 4.10 Sep 30, 2025
@viren-nadkarni viren-nadkarni merged commit e0a4a18 into main Oct 9, 2025
40 checks passed
@viren-nadkarni viren-nadkarni deleted the exc-translate-asf branch October 9, 2025 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs: skip Pull request does not require documentation changes notes: skip Pull request does not have to be mentioned in the release notes semver: patch Non-breaking changes which can be included in patch releases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants