Skip to content

RFC: Allow for user defined exception handling in api gw handler #66

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

Closed
michaelbrewer opened this issue Dec 15, 2021 · 5 comments
Closed

Comments

@michaelbrewer
Copy link
Contributor

Key information

Summary

Allow for a simple way to define error handling

Motivation

Make it easier to define exception handling logic for api gw handlers

Proposal

If this feature should be available in other runtimes (e.g. Java, Typescript), how would this look like to ensure consistency?

User Experience

How would customers use it?

Example UX based on Fast API installing custom exception handlers

app = ApiGatewayResolver()
logger = Logger()


@app.exception_handler(SomeKindOfError)
def handle_error(ex: SomeKindOfError):
   print(f"request path is '{app.current_event.path}'")
   return Response(status_code=418, content_type=content_types.TEXT_HTML, body=str(ex))


@app.not_found()
def handle_not_found(exc: NotFoundError):
    return Response(status_code=404, content_type=content_types.TEXT_PLAIN, body="I am a teapot!")


@app.exception_handler(ServiceError)
def service_error(ex: ServiceError):
    logger.debug(f"Log out sensitive stuff: {ex.msg}")
    return Response(
        status_code=ex.status_code,
        content_type=content_types.APPLICATION_JSON,
        body="CUSTOM ERROR FORMAT",
    )


@app.get("/my/path")
def call_with_error() -> Response:
   raise SomeKindOfError("Foo!")


@app.get("/my/path2")
def call_with_error_sensitive() -> Response:
   raise InternalServiceError("Foo!")


def lambda_handler(event, context):
   return app(event, context)

Any configuration or corner cases you'd expect?

Demonstration of before and after on how the experience will be better

Drawbacks

Why should we not do this?

Make increase overall complexity.

Do we need additional dependencies? Impact performance/package size?

No additional dependencies

Rationale and alternatives

  • What other designs have been considered? Why not them?

Another option is to use Middleware Factor to define error handling. But this is not as intuitive.

  • What is the impact of not doing this?

Unresolved questions

Optional, stash area for topics that need further development e.g. TBD

@michaelbrewer
Copy link
Contributor Author

@heitorlessa - here is an RFC for the exception handling support for API GW. I have an example PR for it as well.

@heitorlessa
Copy link
Contributor

Can we also cover the UX for handling ServiceError like the ones we provide - NotFound, etc?

@michaelbrewer
Copy link
Contributor Author

currently they would be handled for you. so we need to think of a way to not make this a breaking change.

@michaelbrewer
Copy link
Contributor Author

Currently is looks like this:

except ServiceError as e:
    return ResponseBuilder(...)
except Exception as exc:
    handler = self._lookup_exception_handler(exc)
    if handler:
        return ResponseBuilder(handler(exc))
    if self._debug:
        return ResponseBuilder(...)
    raise

We could update it to be handled in _lookup_exception_handler:

except Exception as exc:
    handler = self._lookup_exception_handler(exc)
    if handler:
        return ResponseBuilder(handler(exc))
    if self._debug:
        return ResponseBuilder(...)
    raise

Then _lookup_exception_handler can check if there is a handler and fall back to the standard ones:

def _lookup_exception_handler(exc):
      ...

	  if isinstanceof(ex, ServiceError):
	      return ResponseBuilder(
	          Response(...)

@heitorlessa heitorlessa transferred this issue from aws-powertools/powertools-lambda-python Dec 20, 2021
@heitorlessa
Copy link
Contributor

Now part of 1.23.0 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants