33"""
44
55import asyncio
6- import functools
76import logging
87
98from aiohttp import web
4241 parse_request_path_parameters_as ,
4342 parse_request_query_parameters_as ,
4443)
45- from servicelib .aiohttp .typing_extension import Handler
4644from servicelib .common_headers import (
4745 UNDEFINED_DEFAULT_SIMCORE_USER_AGENT_VALUE ,
4846 X_SIMCORE_USER_AGENT ,
4947)
5048from servicelib .mimetype_constants import MIMETYPE_APPLICATION_JSON
5149from servicelib .rabbitmq import RPCServerError
52- from servicelib .rabbitmq .rpc_interfaces .catalog .errors import (
53- CatalogForbiddenError ,
54- CatalogItemNotFoundError ,
55- )
5650from servicelib .rabbitmq .rpc_interfaces .dynamic_scheduler .errors import (
5751 ServiceWaitingForManualInterventionError ,
5852 ServiceWasNotFoundError ,
6761from ..groups .exceptions import GroupNotFoundError
6862from ..login .decorators import login_required
6963from ..projects .api import has_user_project_access_rights
70- from ..resource_usage .errors import DefaultPricingPlanNotFoundError
7164from ..security .decorators import permission_required
7265from ..users .api import get_user_id_from_gid , get_user_role
73- from ..users .exceptions import UserDefaultWalletNotFoundError
7466from ..utils_aiohttp import envelope_json_response
75- from ..wallets .errors import WalletAccessForbiddenError , WalletNotEnoughCreditsError
7667from . import nodes_utils , projects_service
68+ from ._common .exception_handlers import handle_plugin_requests_exceptions
7769from ._common .models import ProjectPathParams , RequestContext
7870from ._nodes_api import NodeScreenshot , get_node_screenshots
7971from .exceptions import (
80- ClustersKeeperNotAvailableError ,
81- DefaultPricingUnitNotFoundError ,
8272 NodeNotFoundError ,
83- ProjectInDebtCanNotChangeWalletError ,
84- ProjectInvalidRightsError ,
85- ProjectNodeRequiredInputsNotSetError ,
8673 ProjectNodeResourcesInsufficientRightsError ,
8774 ProjectNodeResourcesInvalidError ,
88- ProjectNotFoundError ,
89- ProjectStartsTooManyDynamicNodesError ,
9075)
9176
9277_logger = logging .getLogger (__name__ )
9378
9479
95- def _handle_project_nodes_exceptions (handler : Handler ):
96- @functools .wraps (handler )
97- async def wrapper (request : web .Request ) -> web .StreamResponse :
98- try :
99- return await handler (request )
100-
101- except (
102- ProjectNotFoundError ,
103- NodeNotFoundError ,
104- UserDefaultWalletNotFoundError ,
105- DefaultPricingPlanNotFoundError ,
106- DefaultPricingUnitNotFoundError ,
107- GroupNotFoundError ,
108- CatalogItemNotFoundError ,
109- ) as exc :
110- raise web .HTTPNotFound (reason = f"{ exc } " ) from exc
111- except (
112- WalletNotEnoughCreditsError ,
113- ProjectInDebtCanNotChangeWalletError ,
114- ) as exc :
115- raise web .HTTPPaymentRequired (reason = f"{ exc } " ) from exc
116- except ProjectInvalidRightsError as exc :
117- raise web .HTTPUnauthorized (reason = f"{ exc } " ) from exc
118- except ProjectStartsTooManyDynamicNodesError as exc :
119- raise web .HTTPConflict (reason = f"{ exc } " ) from exc
120- except ClustersKeeperNotAvailableError as exc :
121- raise web .HTTPServiceUnavailable (reason = f"{ exc } " ) from exc
122- except ProjectNodeRequiredInputsNotSetError as exc :
123- raise web .HTTPConflict (reason = f"{ exc } " ) from exc
124- except CatalogForbiddenError as exc :
125- raise web .HTTPForbidden (reason = f"{ exc } " ) from exc
126- except WalletAccessForbiddenError as exc :
127- raise web .HTTPForbidden (
128- reason = f"Payment required, but the user lacks access to the project's linked wallet.: { exc } "
129- ) from exc
130-
131- return wrapper
132-
133-
13480#
13581# projects/*/nodes COLLECTION -------------------------
13682#
@@ -145,7 +91,7 @@ class NodePathParams(ProjectPathParams):
14591@routes .post (f"/{ VTAG } /projects/{{project_id}}/nodes" , name = "create_node" )
14692@login_required
14793@permission_required ("project.node.create" )
148- @_handle_project_nodes_exceptions
94+ @handle_plugin_requests_exceptions
14995async def create_node (request : web .Request ) -> web .Response :
15096 req_ctx = RequestContext .model_validate (request )
15197 path_params = parse_request_path_parameters_as (ProjectPathParams , request )
@@ -187,7 +133,7 @@ async def create_node(request: web.Request) -> web.Response:
187133@routes .get (f"/{ VTAG } /projects/{{project_id}}/nodes/{{node_id}}" , name = "get_node" )
188134@login_required
189135@permission_required ("project.node.read" )
190- @_handle_project_nodes_exceptions
136+ @handle_plugin_requests_exceptions
191137# NOTE: Careful, this endpoint is actually "get_node_state," and it doesn't return a Node resource.
192138async def get_node (request : web .Request ) -> web .Response :
193139 req_ctx = RequestContext .model_validate (request )
@@ -226,7 +172,7 @@ async def get_node(request: web.Request) -> web.Response:
226172)
227173@login_required
228174@permission_required ("project.node.update" )
229- @_handle_project_nodes_exceptions
175+ @handle_plugin_requests_exceptions
230176async def patch_project_node (request : web .Request ) -> web .Response :
231177 req_ctx = RequestContext .model_validate (request )
232178 path_params = parse_request_path_parameters_as (NodePathParams , request )
@@ -247,7 +193,7 @@ async def patch_project_node(request: web.Request) -> web.Response:
247193@routes .delete (f"/{ VTAG } /projects/{{project_id}}/nodes/{{node_id}}" , name = "delete_node" )
248194@login_required
249195@permission_required ("project.node.delete" )
250- @_handle_project_nodes_exceptions
196+ @handle_plugin_requests_exceptions
251197async def delete_node (request : web .Request ) -> web .Response :
252198 req_ctx = RequestContext .model_validate (request )
253199 path_params = parse_request_path_parameters_as (NodePathParams , request )
@@ -275,7 +221,7 @@ async def delete_node(request: web.Request) -> web.Response:
275221)
276222@login_required
277223@permission_required ("project.node.read" )
278- @_handle_project_nodes_exceptions
224+ @handle_plugin_requests_exceptions
279225async def retrieve_node (request : web .Request ) -> web .Response :
280226 """Has only effect on nodes associated to dynamic services"""
281227 path_params = parse_request_path_parameters_as (NodePathParams , request )
@@ -295,7 +241,7 @@ async def retrieve_node(request: web.Request) -> web.Response:
295241)
296242@login_required
297243@permission_required ("project.node.update" )
298- @_handle_project_nodes_exceptions
244+ @handle_plugin_requests_exceptions
299245async def update_node_outputs (request : web .Request ) -> web .Response :
300246 req_ctx = RequestContext .model_validate (request )
301247 path_params = parse_request_path_parameters_as (NodePathParams , request )
@@ -322,7 +268,7 @@ async def update_node_outputs(request: web.Request) -> web.Response:
322268)
323269@login_required
324270@permission_required ("project.update" )
325- @_handle_project_nodes_exceptions
271+ @handle_plugin_requests_exceptions
326272async def start_node (request : web .Request ) -> web .Response :
327273 """Has only effect on nodes associated to dynamic services"""
328274 req_ctx = RequestContext .model_validate (request )
@@ -366,7 +312,7 @@ async def _stop_dynamic_service_task(
366312)
367313@login_required
368314@permission_required ("project.update" )
369- @_handle_project_nodes_exceptions
315+ @handle_plugin_requests_exceptions
370316async def stop_node (request : web .Request ) -> web .Response :
371317 """Has only effect on nodes associated to dynamic services"""
372318 req_ctx = RequestContext .model_validate (request )
@@ -408,7 +354,7 @@ async def stop_node(request: web.Request) -> web.Response:
408354)
409355@login_required
410356@permission_required ("project.node.read" )
411- @_handle_project_nodes_exceptions
357+ @handle_plugin_requests_exceptions
412358async def restart_node (request : web .Request ) -> web .Response :
413359 """Has only effect on nodes associated to dynamic services"""
414360
@@ -432,7 +378,7 @@ async def restart_node(request: web.Request) -> web.Response:
432378)
433379@login_required
434380@permission_required ("project.node.read" )
435- @_handle_project_nodes_exceptions
381+ @handle_plugin_requests_exceptions
436382async def get_node_resources (request : web .Request ) -> web .Response :
437383 req_ctx = RequestContext .model_validate (request )
438384 path_params = parse_request_path_parameters_as (NodePathParams , request )
@@ -465,7 +411,7 @@ async def get_node_resources(request: web.Request) -> web.Response:
465411)
466412@login_required
467413@permission_required ("project.node.update" )
468- @_handle_project_nodes_exceptions
414+ @handle_plugin_requests_exceptions
469415async def replace_node_resources (request : web .Request ) -> web .Response :
470416 req_ctx = RequestContext .model_validate (request )
471417 path_params = parse_request_path_parameters_as (NodePathParams , request )
@@ -524,7 +470,7 @@ class _ProjectGroupAccess(BaseModel):
524470)
525471@login_required
526472@permission_required ("project.read" )
527- @_handle_project_nodes_exceptions
473+ @handle_plugin_requests_exceptions
528474async def get_project_services_access_for_gid (
529475 request : web .Request ,
530476) -> web .Response :
@@ -644,7 +590,7 @@ class _ProjectNodePreview(BaseModel):
644590)
645591@login_required
646592@permission_required ("project.read" )
647- @_handle_project_nodes_exceptions
593+ @handle_plugin_requests_exceptions
648594async def list_project_nodes_previews (request : web .Request ) -> web .Response :
649595 req_ctx = RequestContext .model_validate (request )
650596 path_params = parse_request_path_parameters_as (ProjectPathParams , request )
@@ -684,7 +630,7 @@ async def list_project_nodes_previews(request: web.Request) -> web.Response:
684630)
685631@login_required
686632@permission_required ("project.read" )
687- @_handle_project_nodes_exceptions
633+ @handle_plugin_requests_exceptions
688634async def get_project_node_preview (request : web .Request ) -> web .Response :
689635 req_ctx = RequestContext .model_validate (request )
690636 path_params = parse_request_path_parameters_as (NodePathParams , request )
0 commit comments