Skip to content

DEVC-601: Add app logic for meaningful error when mismatched app type is used#91

Merged
kossman merged 25 commits intomasterfrom
feature/DEVC-601-meaningful-error-on-mismatched-app-type-used
Feb 10, 2025
Merged

DEVC-601: Add app logic for meaningful error when mismatched app type is used#91
kossman merged 25 commits intomasterfrom
feature/DEVC-601-meaningful-error-on-mismatched-app-type-used

Conversation

@kossman
Copy link
Copy Markdown
Contributor

@kossman kossman commented Jan 25, 2025

Rationale

We have to add changes to be aligned with node-sdk changes
node-sdk Jira task
node-sdk PR

Changes

Mainly, changes are related to two validations:

  1. check app_type declared at manifest.json file and compare it with raw_event_type passed at specific app decorator to base_handler and raise an error if a mismatch happens
  2. check app_type based on the event payload passed to lambda_handler and app decorator itself, the logic here is the same if they aren't matched - raise the error
    So thus, changes were encapsulated into function validate_app_type_context which can handle both 1 and 2 corva app use cases.

Under the hood validate_app_type_context has:

  • validate_manifested_type: will be called only if get_manifested_type() could extract correct app_type name from manifest.json file
  • validate_event_payload: will be called otherwise. Under the hood get_event_type func will trying to find the appropriate child cls inherited from RawBaseEvent and then - validate matching.

The idea is the following: each existing (and future added) specific event type eventually should be inherited from one of 3 raw Raw{APP_TYPE}Event classes, so we can just check this "belonging"

JIRA ticket

TODO

  • Update CHANGELOG.md

@kossman kossman self-assigned this Jan 25, 2025
@kossman kossman marked this pull request as ready for review January 27, 2025 12:14
Copy link
Copy Markdown
Contributor

@vladbagmet vladbagmet left a comment

Choose a reason for hiding this comment

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

praise: Awesome description for the pull request! 👍

question (blocking): Can validation be done inside base_handler?

Comment thread src/corva/handlers.py Outdated
func: Callable,
raw_event_type: Type[RawBaseEvent],
handler: Optional[logging.Handler],
app_decorator_type: str,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question (blocking): Can we use raw_event_type to identify type?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ohh, yeah, great idea! Thanks for catching it! 🙌

Comment thread src/corva/validate_app_init.py Outdated
from corva.models.stream.raw import RawStreamEvent
from corva.models.task import RawTaskEvent

BASE_EVENT_CLS_TO_APP_TYPE_MAPPING: Dict[str, Type[RawBaseEvent]] = {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question (bloacking): Do we really need to have this mapping? RawTaskEvent, RawStreamEvent and RawScheduledEvent have the same parent class.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

After applying changes proposed here I've removed this BASE_EVENT_CLS_TO_APP_TYPE_MAPPING at all
Thanks!

Comment thread src/corva/validate_app_init.py Outdated

def validate_manifested_type(manifest: Dict[str, Any], app_decorator_type: str) -> None:
manifest_app_type = manifest.get("application", {}).get("type")
if manifest_app_type and manifest_app_type != app_decorator_type:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question (blocking): What if we have manifest.json without type. Should this validation pass in this case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Also updated the logic for handle such cases, I believe if app type missed at manifest.json we anyway should try to validate app call basing on event payload.
But at the same time I've also added check for app_type, so if manifest has wrong app_type code will throw an error, please take a look over this test 🙏

@kossman kossman requested a review from vladbagmet January 28, 2025 16:00
Comment thread src/corva/handlers.py Outdated
if merge_events:
aws_event = _merge_events(aws_event, data_transformation_type)

validate_app_type_context(aws_event, raw_event_type)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question(blocking): Should validation happen before calling anything else?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@vladbagmet I've refactored a bit base_handler body 🙏
But anyway as I see, more convenient way to place validate_app_type_context func right after _merge_events(...) coz in this case merging validation logic called first + it's easier to guess_event_type(aws_event) if the event already merged 🤔 wdyt?

Comment thread src/corva/validate_app_init.py Outdated
)


@functools.lru_cache(maxsize=None)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question (non-blocking): Is this cache going to be used between lamba function calls? If, so why don't we limit number of cached instances?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

you're right, limited to 1, thanks 🙌

Comment thread src/corva/models/base.py
import pydantic


class AppType(str, Enum):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

note: I like that we do not have mapping dict now. Also, is there a way to use already existing models for event to identify the app type?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure that I've got your point, could you please explain a bit wider 🙏

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

neatpick: Seems like AppType is type of app defined in manifest.json.

raw_event["event_type"] = "unknown_event_type"
with pytest.raises(ValidationError) as e:

with pytest.raises(RuntimeError) as e:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question (non-blocking): If app type is correct, but schema of this event is corrupted, should ValidationError still be raised?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Seems you're right, I've updated a bit app logic and have reverted the test logic accordingly, thanks for reviewing 🙌

@kossman kossman changed the title add app logic for meaningful error when mismatched app type is used feat(DEVC-601): Add app logic for meaningful error when mismatched app type is used Feb 7, 2025
@kossman kossman changed the title feat(DEVC-601): Add app logic for meaningful error when mismatched app type is used DEVC-601: Add app logic for meaningful error when mismatched app type is used Feb 7, 2025
Comment thread src/corva/handlers.py Outdated
if merge_events:
aws_event = _merge_events(aws_event, data_transformation_type)

if is_direct_app_call:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question (blocking): Should more specific check goes first?

Comment thread src/corva/models/base.py Outdated
pass

@classmethod
def get_app_type(cls) -> AppType:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue(blocking): Event payload types and type defined in manifest.json are not the same. What do you think about removing this method from the interface and do types comparison in "validate_app_type_context" method.

Comment thread src/corva/validate_app_init.py Outdated
return leaf_classes


def guess_event_type(aws_event: Any) -> Optional[Type[RawBaseEvent]]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

question(non-blocking): Can we rename it to get_event_type?

)


@functools.lru_cache(maxsize=1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

though(non-blocking): Please be advised that this approach can not work between lamba calls.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

But anyway, I think we can keep such logic here to be prepared for provisioned_concurrency in the future after changes on packager side are rolled out 🙏

@vladbagmet vladbagmet self-requested a review February 7, 2025 10:42
Copy link
Copy Markdown
Contributor

@vladbagmet vladbagmet left a comment

Choose a reason for hiding this comment

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

Blocking things are:

  • Revert changes (def get_app_type(cls) -> AppType:)
  • Change order of checks.

@kossman
Copy link
Copy Markdown
Contributor Author

kossman commented Feb 7, 2025

Blocking things are:

  • Revert changes (def get_app_type(cls) -> AppType:)
  • Change order of checks.

@vladbagmet proposed changes are integrated, thanks!

@kossman kossman requested a review from vladbagmet February 7, 2025 11:28
Copy link
Copy Markdown
Contributor

@vladbagmet vladbagmet left a comment

Choose a reason for hiding this comment

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

praise: Great job!

🥇

@kossman kossman merged commit 0136cd9 into master Feb 10, 2025
@kossman kossman deleted the feature/DEVC-601-meaningful-error-on-mismatched-app-type-used branch February 10, 2025 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants