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

Speed up exception handling by re-using Environments #7143

Merged
merged 7 commits into from
Dec 20, 2023
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
cleanup
jogo committed Dec 19, 2023
commit f994292cdda57622ffbd47568e9a151bff72cdee
5 changes: 4 additions & 1 deletion moto/cloudfront/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any

from jinja2 import DictLoader, Environment

from moto.core.exceptions import RESTError

EXCEPTION_RESPONSE = """<?xml version="1.0"?>
@@ -17,7 +18,9 @@
class CloudFrontException(RESTError):
code = 400
extended_templates = {"cferror": EXCEPTION_RESPONSE}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, error_type: str, message: str, **kwargs: Any):
kwargs.setdefault("template", "cferror")
10 changes: 8 additions & 2 deletions moto/core/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import Any, List, Optional, Tuple
from typing import Any, Dict, List, Optional, Tuple

from jinja2 import DictLoader, Environment
from werkzeug.exceptions import HTTPException
@@ -64,7 +64,7 @@ def __init__(
self.message = message

if template in self.templates.keys():
self.description: str = self.env.get_template(template).render(
self.description: str = self.__class__.env.get_template(template).render(
error_type=error_type,
message=message,
request_id_tag=self.request_id_tag_name,
@@ -95,6 +95,12 @@ def to_json(self) -> "JsonRESTError":
err.code = self.code
return err

@classmethod
def extended_templates(cls, extended_templates: Dict) -> Dict:
# Can be simplified to cls.templates | extended_templates when we drop Python 3.8 support
# https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
return dict(cls.templates.items() | extended_templates.items())


class DryRunClientError(RESTError):
code = 412
5 changes: 4 additions & 1 deletion moto/ec2/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any, Iterable, List, Optional, Union

from jinja2 import DictLoader, Environment

from moto.core.exceptions import RESTError

# EC2 has a custom root-tag - <Response> vs <ErrorResponse>
@@ -24,7 +25,9 @@ class EC2ClientError(RESTError):
# EC2 uses <RequestID> as tag name in the XML response
request_id_tag_name = "RequestID"
extended_templates = {"custom_response": EC2_ERROR_RESPONSE}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, *args: Any, **kwargs: Any):
kwargs.setdefault("template", "custom_response")
6 changes: 4 additions & 2 deletions moto/elasticache/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any

from jinja2 import DictLoader, Environment

from moto.core.exceptions import RESTError

EXCEPTION_RESPONSE = """<?xml version="1.0"?>
@@ -18,11 +19,12 @@ class ElastiCacheException(RESTError):

code = 400
extended_templates = {"ecerror": EXCEPTION_RESPONSE}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, code: str, message: str, **kwargs: Any):
kwargs.setdefault("template", "ecerror")
self.templates["ecerror"] = EXCEPTION_RESPONSE
super().__init__(code, message)


5 changes: 4 additions & 1 deletion moto/elasticbeanstalk/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any

from jinja2 import DictLoader, Environment

from moto.core.exceptions import RESTError

EXCEPTION_RESPONSE = """<?xml version="1.0"?>
@@ -18,7 +19,9 @@ class ElasticBeanstalkException(RESTError):

code = 400
extended_templates = {"ecerror": EXCEPTION_RESPONSE}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, code: str, message: str, **kwargs: Any):
kwargs.setdefault("template", "ecerror")
5 changes: 4 additions & 1 deletion moto/s3/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import TYPE_CHECKING, Any, Optional, Union

from jinja2 import DictLoader, Environment

from moto.core.exceptions import RESTError

if TYPE_CHECKING:
@@ -51,7 +52,9 @@ class S3ClientError(RESTError):
"range_error": ERROR_WITH_RANGE,
"storage_error": ERROR_WITH_STORAGE_CLASS,
}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, *args: Any, **kwargs: Any):
kwargs.setdefault("template", "single_error")
5 changes: 4 additions & 1 deletion moto/s3control/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any

from jinja2 import DictLoader, Environment

from moto.core.exceptions import RESTError

ERROR_WITH_ACCESS_POINT_NAME = """{% extends 'wrapped_single_error' %}
@@ -18,7 +19,9 @@ class S3ControlError(RESTError):
"ap_not_found": ERROR_WITH_ACCESS_POINT_NAME,
"apf_not_found": ERROR_WITH_ACCESS_POINT_POLICY,
}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, *args: Any, **kwargs: Any):
kwargs.setdefault("template", "single_error")
5 changes: 4 additions & 1 deletion moto/sagemaker/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any

from jinja2 import DictLoader, Environment

from moto.core.exceptions import AWSError, JsonRESTError, RESTError

ERROR_WITH_MODEL_NAME = """{% extends 'single_error' %}
@@ -10,7 +11,9 @@

class SagemakerClientError(RESTError):
extended_templates = {"model_error": ERROR_WITH_MODEL_NAME}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, *args: Any, **kwargs: Any):
kwargs.setdefault("template", "single_error")
11 changes: 8 additions & 3 deletions moto/sdb/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Exceptions raised by the sdb service."""
from typing import Any

from moto.core.exceptions import RESTError
from jinja2 import DictLoader, Environment

from moto.core.exceptions import RESTError

SDB_ERROR = """<?xml version="1.0"?>
<Response>
<Errors>
@@ -20,7 +21,9 @@
class InvalidParameterError(RESTError):
code = 400
extended_templates = {"sdb_error": SDB_ERROR}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, **kwargs: Any):
kwargs.setdefault("template", "sdb_error")
@@ -41,7 +44,9 @@ def __init__(self, domain_name: str):
class UnknownDomainName(RESTError):
code = 400
extended_templates = {"sdb_error": SDB_ERROR}
env = Environment(loader=DictLoader(RESTError.templates | extended_templates))
env = Environment(
loader=DictLoader(RESTError.extended_templates(extended_templates))
)

def __init__(self, **kwargs: Any):
kwargs.setdefault("template", "sdb_error")