Skip to content

Commit 34a9f54

Browse files
authored
Ensure cylc message exceptions are printed to stderr (#6647)
Ensure `cylc message` exceptions are printed to stderr
1 parent 16c0e6c commit 34a9f54

File tree

4 files changed

+59
-16
lines changed

4 files changed

+59
-16
lines changed

changes.d/6647.fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Ensure `cylc message` exceptions are printed to `job.err`.

cylc/flow/task_message.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ def write_messages(workflow, job_id, messages, event_time):
102102
_append_job_status_file(workflow, job_id, event_time, messages)
103103

104104

105-
def send_messages(workflow, job_id, messages, event_time):
105+
def send_messages(
106+
workflow: str, job_id: str, messages: List[list], event_time: str
107+
) -> None:
106108
workflow = os.path.normpath(workflow)
107109
try:
108110
pclient = get_client(workflow)
@@ -111,23 +113,24 @@ def send_messages(workflow, job_id, messages, event_time):
111113
# either the workflow is stopped or the contact file is not present
112114
# on the job host (i.e. comms method is polling)
113115
# eitherway don't try messaging
114-
pass
115-
except Exception:
116-
# Backward communication not possible
116+
return
117+
except Exception as exc:
118+
print(f"{type(exc).__name__}: {exc}", file=sys.stderr)
117119
if cylc.flow.flags.verbosity > 1:
118120
import traceback
119121
traceback.print_exc()
120-
else:
121-
mutation_kwargs = {
122-
'request_string': MUTATION,
123-
'variables': {
124-
'wFlows': [workflow],
125-
'taskJob': job_id,
126-
'eventTime': event_time,
127-
'messages': messages,
128-
}
122+
# cylc message shouldn't fail if the client can't initialize.
123+
return
124+
mutation_kwargs = {
125+
'request_string': MUTATION,
126+
'variables': {
127+
'wFlows': [workflow],
128+
'taskJob': job_id,
129+
'eventTime': event_time,
130+
'messages': messages,
129131
}
130-
pclient('graphql', mutation_kwargs)
132+
}
133+
pclient('graphql', mutation_kwargs)
131134

132135

133136
def _append_job_status_file(workflow, job_id, event_time, messages):
@@ -138,7 +141,8 @@ def _append_job_status_file(workflow, job_id, event_time, messages):
138141
try:
139142
job_status_file = open(job_log_name + '.status', 'a') # noqa: SIM115
140143
# TODO: niceify read/write/appending messages to this file
141-
except IOError:
144+
except IOError as exc:
145+
print(f"{type(exc).__name__}: {exc}", file=sys.stderr)
142146
if cylc.flow.flags.verbosity > 1:
143147
import traceback
144148
traceback.print_exc()

tests/functional/cylc-message/00-ssh/flow.cylc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[runtime]
1010
[[t0]]
1111
script = """
12-
cylc broadcast "${CYLC_WORKFLOW_ID}" '--name=t1' '--set=script="true"'
12+
cylc broadcast "${CYLC_WORKFLOW_ID}" --name=t1 --set=script="true"
1313
"""
1414
platform = {{ environ['CYLC_TEST_PLATFORM'] }}
1515
[[t1]]

tests/unit/test_task_message.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
2+
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
3+
#
4+
# This program is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
from socket import gaierror
18+
19+
import pytest
20+
21+
from cylc.flow.task_message import send_messages
22+
23+
24+
def test_send_messages_err(
25+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture
26+
):
27+
"""If an error occurs while initializing the client, it should be printed.
28+
"""
29+
exc_msg = 'Relic malfunction detected'
30+
31+
def mock_get_client(*a, **k):
32+
raise gaierror(-2, exc_msg)
33+
34+
monkeypatch.setattr('cylc.flow.task_message.get_client', mock_get_client)
35+
send_messages(
36+
'arasaka', '1/v/01', [['INFO', 'silverhand']], '2077-01-01T00:00:00Z'
37+
)
38+
assert f"gaierror: [Errno -2] {exc_msg}" in capsys.readouterr().err

0 commit comments

Comments
 (0)