Skip to content

Commit 429e94d

Browse files
committed
DM-51010: cm-client
- do not dump traceback in cli - return 422 instead of 500 for unretriable client errors
1 parent 8733b56 commit 429e94d

File tree

6 files changed

+35
-13
lines changed

6 files changed

+35
-13
lines changed

src/lsst/cmservice/cli/options.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import sys
12
from collections.abc import Callable
23
from enum import Enum, auto
34
from functools import partial, wraps
45
from typing import Any, cast
56

67
import click
78
from click.decorators import FC
9+
from httpx import HTTPStatusError
810

911
from ..client.client import CMClient
1012
from ..common.enums import (
@@ -14,6 +16,7 @@
1416
NodeTypeEnum,
1517
StatusEnum,
1618
)
19+
from ..common.logging import LOGGER
1720

1821
__all__ = [
1922
"cmclient",
@@ -65,6 +68,8 @@
6568
"yaml_file",
6669
]
6770

71+
logger = LOGGER.bind(module=__name__)
72+
6873

6974
class DictParamType(click.ParamType):
7075
"""Represents the dictionary type of a CLI parameter.
@@ -514,7 +519,12 @@ def decorator(f: FC) -> FC:
514519
@wraps(f)
515520
def wrapper(*args: Any, **kwargs: Any) -> Any:
516521
kwargs["client"] = CMClient()
517-
return f(*args, **kwargs)
522+
try:
523+
response = f(*args, **kwargs)
524+
return response
525+
except HTTPStatusError as e:
526+
logger.error(e.response.text)
527+
sys.exit(1)
518528

519529
return cast(FC, wrapper)
520530

src/lsst/cmservice/db/node.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,9 @@ async def reject(
594594
Node being rejected
595595
"""
596596
if self.status in [StatusEnum.accepted, StatusEnum.rescued]:
597-
raise CMBadStateTransitionError(f"Can not reject {self} as it is in status {self.status}")
597+
raise CMBadStateTransitionError(
598+
f"Can not reject {self.fullname} as it is in status {self.status}"
599+
)
598600

599601
await self.update_values(session, status=StatusEnum.rejected)
600602
if self.level is LevelEnum.campaign:
@@ -625,7 +627,9 @@ async def accept(
625627
StatusEnum.reviewable,
626628
StatusEnum.rescuable,
627629
]:
628-
raise CMBadStateTransitionError(f"Can not accept {self} as it is in status {self.status}")
630+
raise CMBadStateTransitionError(
631+
f"Can not accept {self.fullname} as it is in status {self.status}"
632+
)
629633

630634
await self.update_values(session, status=StatusEnum.accepted)
631635

@@ -657,7 +661,7 @@ async def reset(
657661
Node being reset
658662
"""
659663
if self.status not in [StatusEnum.blocked, StatusEnum.rejected, StatusEnum.failed, StatusEnum.ready]:
660-
raise CMBadStateTransitionError(f"Can not reset {self} as it is in status {self.status}")
664+
raise CMBadStateTransitionError(f"Can not reset {self.fullname} as it is in status {self.status}")
661665

662666
await self._clean_up_node(session, fake_reset=fake_reset)
663667
await self.update_values(session, status=StatusEnum.waiting, superseded=False)

src/lsst/cmservice/db/row.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ async def delete_row(
215215
pass
216216
elif hasattr(row, "status") and row.status not in DELETABLE_STATES:
217217
raise CMBadStateTransitionError(
218-
f"Can not delete a row because it is in use {row} {row.status}",
218+
f"Can not delete a row because it is in use {row.fullname} {row.status}",
219219
)
220220
try:
221221
await session.delete(row)

src/lsst/cmservice/routers/wrappers.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
from .. import db, models
2121
from ..common.enums import StatusEnum
22-
from ..common.errors import CMMissingFullnameError, CMMissingIDError
22+
from ..common.errors import CMBadStateTransitionError, CMMissingFullnameError, CMMissingIDError
2323

2424
logger = get_logger(__name__)
2525

@@ -811,6 +811,8 @@ async def update_node_status(
811811
except CMMissingIDError as msg:
812812
logger.info(msg)
813813
raise HTTPException(status_code=404, detail=str(msg)) from msg
814+
except CMBadStateTransitionError as e:
815+
raise HTTPException(status_code=422, detail=str(e)) from e
814816
except Exception as msg:
815817
logger.error(msg, exc_info=True)
816818
raise HTTPException(status_code=500, detail=str(msg)) from msg
@@ -1098,9 +1100,11 @@ async def node_reject(
10981100
the_node = await db_class.get_row(session, row_id)
10991101
ret_val = await the_node.reject(session)
11001102
return ret_val
1101-
except CMMissingIDError as msg:
1102-
logger.info(msg)
1103-
raise HTTPException(status_code=404, detail=str(msg)) from msg
1103+
except CMMissingIDError as e:
1104+
logger.info(e)
1105+
raise HTTPException(status_code=404, detail=str(e)) from e
1106+
except CMBadStateTransitionError as e:
1107+
raise HTTPException(status_code=422, detail=str(e)) from e
11041108
except Exception as e:
11051109
logger.error(e, exc_info=True)
11061110
raise HTTPException(status_code=500, detail=str(e)) from e
@@ -1150,6 +1154,8 @@ async def node_accept(
11501154
except CMMissingIDError as msg:
11511155
logger.info(msg)
11521156
raise HTTPException(status_code=404, detail=str(msg)) from msg
1157+
except CMBadStateTransitionError as e:
1158+
raise HTTPException(status_code=422, detail=str(e)) from e
11531159
except Exception as e:
11541160
logger.error(e, exc_info=True)
11551161
raise HTTPException(status_code=500, detail=str(e)) from e
@@ -1200,6 +1206,8 @@ async def node_reset(
12001206
except CMMissingIDError as msg:
12011207
logger.info(msg)
12021208
raise HTTPException(status_code=404, detail=str(msg)) from msg
1209+
except CMBadStateTransitionError as e:
1210+
raise HTTPException(status_code=422, detail=str(e)) from e
12031211
except Exception as e:
12041212
logger.error(e, exc_info=True)
12051213
raise HTTPException(status_code=500, detail=str(e)) from e

src/lsst/cmservice/templates/wms_submit_sh.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ set -e
1111
{#- Assuming native environment already setup #}
1212
{%- elif script_method == "htcondor" %}
1313
export LSST_VERSION="{{ lsst_version }}"
14-
export LSST_DISTRIB_DIR="{{ lsst_distrib_dir }}"
14+
export LSST_DISTRIB_DIR="{{ lsst_distrib_dir.rstrip("/") }}"
1515
source ${LSST_DISTRIB_DIR}/${LSST_VERSION}/loadLSST.bash
1616
setup lsst_distrib
1717
{# BLANK LINE #}

tests/routers/util_functions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ async def check_update_methods(
401401
response = await client.post(
402402
f"{config.asgi.prefix}/{api_version}/{entry_class_name}/action/{entry.id}/accept",
403403
)
404-
expect_failed_response(response, 500)
404+
expect_failed_response(response, 422)
405405

406406
update_status_model.status = StatusEnum.running
407407
response = await client.post(
@@ -450,13 +450,13 @@ async def check_update_methods(
450450
response = await client.post(
451451
f"{config.asgi.prefix}/{api_version}/{entry_class_name}/action/{entry.id}/reject",
452452
)
453-
expect_failed_response(response, 500)
453+
expect_failed_response(response, 422)
454454

455455
response = await client.post(
456456
f"{config.asgi.prefix}/{api_version}/{entry_class_name}/action/{entry.id}/reset",
457457
content=reset_model.model_dump_json(),
458458
)
459-
expect_failed_response(response, 500)
459+
expect_failed_response(response, 422)
460460

461461
# FIXME this delete test is meant to fail, but the application now allows
462462
# deletion of objects in an "accepted" state, and downstream tests

0 commit comments

Comments
 (0)