update/software/software/api/app.py
Bin Qian e8ed7f2412 Unified error handling
This change includes:
1. defined base exception classe for user visible error
   and non user visible errors (all others exceptions)
2. exception hook to handle exception during processing requests with
   proper user information preparation

An error signature is a few bytes from hash of stack trace of an
exception.

Corresponding client code change will be in separated commit.

Story: 2010676
Task: 49519
Test Cases:
   Pass: unhandled exception will not fail the service.
   Pass: raise SoftwareServiceError exception on server side, correct
response sends to the client side
   Pass: raise None SoftwareServiceError exception (any exception),
correct response sends to the client side.

Change-Id: Ib44eed3261891c4cc3d1931a6f7e2cb707e89b9c
Signed-off-by: Bin Qian <bin.qian@windriver.com>
2024-02-06 20:13:19 +00:00

64 lines
1.7 KiB
Python

"""
Copyright (c) 2023-2024 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import pecan
from software.config import CONF
from software.utils import ExceptionHook
def get_pecan_config():
"""Load the pecan configuration."""
pecan_opts = CONF.pecan
cfg_dict = {
# todo(abailey): add server defaults to config
"server": {
"port": "5496",
"host": "127.0.0.1"
},
"app": {
"root": pecan_opts.root,
"modules": pecan_opts.modules,
"debug": pecan_opts.debug,
"auth_enable": pecan_opts.auth_enable,
"force_canonical": pecan_opts.force_canonical,
"guess_content_type_from_ext":
pecan_opts.guess_content_type_from_ext,
}
}
return pecan.configuration.conf_from_dict(cfg_dict)
def setup_app(pecan_config=None):
"""Setup the pecan REST API."""
if not pecan_config:
pecan_config = get_pecan_config()
pecan.configuration.set_config(dict(pecan_config), overwrite=True)
hook_list = [ExceptionHook()]
# todo(abailey): It seems like the call to pecan.configuration above
# mean that the following lines are redundnant?
app = pecan.make_app(
pecan_config.app.root,
debug=pecan_config.app.debug,
hooks=hook_list,
force_canonical=pecan_config.app.force_canonical,
guess_content_type_from_ext=pecan_config.app.guess_content_type_from_ext
)
return app
class VersionSelectorApplication(object):
def __init__(self):
pc = get_pecan_config()
self.v1 = setup_app(pecan_config=pc)
def __call__(self, environ, start_response):
return self.v1(environ, start_response)