Skip to content

Commit 9031849

Browse files
committed
improves error handling
1 parent 876ec4a commit 9031849

File tree

4 files changed

+65
-25
lines changed

4 files changed

+65
-25
lines changed

services/web/server/src/simcore_service_webserver/studies_dispatcher/_errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ class InvalidRedirectionParamsError(StudyDispatcherError):
2525

2626
class GuestUsersLimitError(StudyDispatcherError):
2727
msg_template = "Maximum number of guests was reached. Please login with a registered user or try again later"
28+
29+
30+
class GuestUserNotAllowedError(StudyDispatcherError):
31+
msg_template = "Guest users are not allowed to access this resource configuration."

services/web/server/src/simcore_service_webserver/studies_dispatcher/_redirects_handlers.py

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@
1717
from servicelib.logging_errors import create_troubleshootting_log_kwargs
1818

1919
from ..dynamic_scheduler import api as dynamic_scheduler_service
20+
from ..exception_handling import create_error_context_from_request
2021
from ..products import products_web
2122
from ..utils import compose_support_error_msg
2223
from ..utils_aiohttp import create_redirect_to_page_response, get_api_base_url
2324
from ._catalog import ValidService, validate_requested_service
24-
from ._constants import MSG_UNEXPECTED_DISPATCH_ERROR
25+
from ._constants import MSG_GUESTS_NOT_ALLOWED, MSG_UNEXPECTED_DISPATCH_ERROR
2526
from ._core import validate_requested_file, validate_requested_viewer
26-
from ._errors import InvalidRedirectionParamsError, StudyDispatcherError
27+
from ._errors import (
28+
GuestUserNotAllowedError,
29+
InvalidRedirectionParamsError,
30+
StudyDispatcherError,
31+
)
2732
from ._models import FileParams, ServiceInfo, ServiceParams, ViewerInfo
2833
from ._projects import (
2934
get_or_create_project_with_file,
@@ -92,29 +97,63 @@ async def wrapper(request: web.Request) -> web.StreamResponse:
9297
# NOTE: that response is a redirection that is reraised and not returned
9398
raise
9499

95-
except StudyDispatcherError as err:
100+
except GuestUserNotAllowedError as err:
96101
raise _create_redirect_response_to_error_page(
97102
request.app,
98-
message=f"Sorry, we cannot dispatch your study: {err}",
99-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, # 422
103+
message=MSG_GUESTS_NOT_ALLOWED,
104+
status_code=status.HTTP_401_UNAUTHORIZED,
100105
) from err
101106

102-
except web.HTTPUnauthorized as err:
107+
except StudyDispatcherError as err:
103108
raise _create_redirect_response_to_error_page(
104109
request.app,
105-
message=f"{err.text}. Please reload this page to login/register.",
106-
status_code=err.status_code,
110+
message=f"Sorry, we cannot dispatch your study: {err}",
111+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, # 422
107112
) from err
108113

109114
except web.HTTPUnprocessableEntity as err:
115+
# Validation error in query parameters
116+
error_code = create_error_code(err)
117+
user_error_msg = compose_support_error_msg(
118+
msg="Invalid query parameters in link", error_code=error_code
119+
)
120+
121+
_logger.exception(
122+
**create_troubleshootting_log_kwargs(
123+
user_error_msg,
124+
error=err,
125+
error_code=error_code,
126+
error_context=create_error_context_from_request(request),
127+
tip="The link might be corrupted",
128+
)
129+
)
130+
110131
raise _create_redirect_response_to_error_page(
111132
request.app,
112-
message=f"Invalid parameters in link: {err.text}",
113-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, # 422
133+
message=user_error_msg,
134+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
114135
) from err
115136

116137
except web.HTTPClientError as err:
117-
_logger.exception("Client error with status code %d", err.status_code)
138+
error_code = create_error_code(err)
139+
user_error_msg = compose_support_error_msg(
140+
msg="Fatal error while redirecting request", error_code=error_code
141+
)
142+
143+
_logger.exception(
144+
**create_troubleshootting_log_kwargs(
145+
user_error_msg,
146+
error=err,
147+
error_code=error_code,
148+
error_context={
149+
**create_error_context_from_request(request),
150+
"reason": err.reason,
151+
"status": err.status,
152+
},
153+
tip="The link might be corrupted",
154+
)
155+
)
156+
118157
raise _create_redirect_response_to_error_page(
119158
request.app,
120159
message=err.reason,
@@ -132,7 +171,7 @@ async def wrapper(request: web.Request) -> web.StreamResponse:
132171
user_error_msg,
133172
error=err,
134173
error_code=error_code,
135-
error_context={"request": request},
174+
error_context=create_error_context_from_request(request),
136175
tip="Unexpected failure while dispatching study",
137176
)
138177
)

services/web/server/src/simcore_service_webserver/studies_dispatcher/_rest_handlers.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
""" Handles requests to the Rest API
1+
"""Handles requests to the Rest API"""
22

3-
"""
43
import logging
54
from dataclasses import asdict
65

@@ -50,8 +49,8 @@ def _compose_service_only_dispatcher_prefix_url(
5049
request: web.Request, service_key: str, service_version: str
5150
) -> HttpUrl:
5251
params = ViewerQueryParams(
53-
viewer_key=ServiceKey(service_key),
54-
viewer_version=ServiceVersion(service_version),
52+
viewer_key=TypeAdapter(ServiceKey).validate_python(service_key),
53+
viewer_version=TypeAdapter(ServiceVersion).validate_python(service_version),
5554
).model_dump(exclude_none=True, exclude_unset=True)
5655
absolute_url = request.url.join(
5756
request.app.router["get_redirection_to_viewer"].url_for().with_query(**params)
@@ -202,8 +201,3 @@ async def list_default_viewers(request: Request):
202201
)
203202
]
204203
return envelope_json_response(viewers)
205-
206-
207-
rest_handler_functions = {
208-
fun.__name__: fun for fun in [list_default_viewers, list_viewers]
209-
}

services/web/server/src/simcore_service_webserver/studies_dispatcher/_users.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@
3737
from ..security import security_service, security_web
3838
from ..users import users_service
3939
from ..users.exceptions import UserNotFoundError
40-
from ._constants import MSG_GUESTS_NOT_ALLOWED
41-
from ._errors import GuestUsersLimitError
40+
from ._errors import GuestUserNotAllowedError, GuestUsersLimitError
4241
from .settings import StudiesDispatcherSettings, get_plugin_settings
4342

4443
_logger = logging.getLogger(__name__)
@@ -187,7 +186,7 @@ async def get_or_create_guest_user(
187186
allow_anonymous_or_guest_users -- if True, it will create a temporary GUEST account
188187
189188
Raises:
190-
web.HTTPUnauthorized if ANONYMOUS users are not allowed (either w/o auth or as GUEST)
189+
GuestUserNotAllowedError if ANONYMOUS users are not allowed (either w/o auth or as GUEST)
191190
192191
"""
193192
user = None
@@ -205,7 +204,11 @@ async def get_or_create_guest_user(
205204

206205
if not allow_anonymous_or_guest_users and (not user or user.get("role") == GUEST):
207206
# NOTE: if allow_anonymous_users=False then GUEST users are NOT allowed!
208-
raise web.HTTPUnauthorized(text=MSG_GUESTS_NOT_ALLOWED)
207+
raise GuestUserNotAllowedError(
208+
allow_anonymous_or_guest_users=allow_anonymous_or_guest_users,
209+
user=user,
210+
is_anonymous_user=is_anonymous_user,
211+
)
209212

210213
assert isinstance(user, dict) # nosec
211214

0 commit comments

Comments
 (0)