From ed0b5ac93963c4ba84bef26d67ceb0266b40c1c1 Mon Sep 17 00:00:00 2001 From: Serge Tupchii Date: Fri, 22 Mar 2024 16:39:52 +0200 Subject: [PATCH] fix(emqx_mgmt): handle client shutdown errors in call_client The client process may be shutdown normally during/shortly before the call. --- apps/emqx_management/src/emqx_mgmt.erl | 12 +++++++++++- apps/emqx_management/src/emqx_mgmt_api_clients.erl | 9 ++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/emqx_management/src/emqx_mgmt.erl b/apps/emqx_management/src/emqx_mgmt.erl index 0a3567fb2..35908d3bd 100644 --- a/apps/emqx_management/src/emqx_mgmt.erl +++ b/apps/emqx_management/src/emqx_mgmt.erl @@ -514,7 +514,7 @@ do_call_client(ClientId, Req) -> Pid = lists:last(Pids), case emqx_cm:get_chan_info(ClientId, Pid) of #{conninfo := #{conn_mod := ConnMod}} -> - erlang:apply(ConnMod, call, [Pid, Req]); + call_conn(ConnMod, Pid, Req); undefined -> {error, not_found} end @@ -703,3 +703,13 @@ check_results(Results) -> default_row_limit() -> ?DEFAULT_ROW_LIMIT. + +call_conn(ConnMod, Pid, Req) -> + try + erlang:apply(ConnMod, call, [Pid, Req]) + catch + exit:R when R =:= shutdown; R =:= normal -> + {error, shutdown}; + exit:{R, _} when R =:= shutdown; R =:= noproc -> + {error, shutdown} + end. diff --git a/apps/emqx_management/src/emqx_mgmt_api_clients.erl b/apps/emqx_management/src/emqx_mgmt_api_clients.erl index 70393c520..dd65c1245 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_clients.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_clients.erl @@ -90,6 +90,11 @@ message => <<"Client ID not found">> }). +-define(CLIENT_SHUTDOWN, #{ + code => 'CLIENT_SHUTDOWN', + message => <<"Client connection has been shutdown">> +}). + namespace() -> undefined. api_spec() -> @@ -941,7 +946,7 @@ client_msgs_schema(OpId, Desc, ContExample, RespSchema) -> ['INVALID_PARAMETER'], <<"Invalid parameters">> ), 404 => emqx_dashboard_swagger:error_codes( - ['CLIENTID_NOT_FOUND'], <<"Client ID not found">> + ['CLIENTID_NOT_FOUND', 'CLIENT_SHUTDOWN'], <<"Client ID not found">> ), ?NOT_IMPLEMENTED => emqx_dashboard_swagger:error_codes( ['NOT_IMPLEMENTED'], <<"API not implemented">> @@ -1220,6 +1225,8 @@ list_client_msgs(MsgType, ClientID, QString) -> case emqx_mgmt:list_client_msgs(MsgType, ClientID, PagerParams) of {error, not_found} -> {404, ?CLIENTID_NOT_FOUND}; + {error, shutdown} -> + {404, ?CLIENT_SHUTDOWN}; {error, not_implemented} -> {?NOT_IMPLEMENTED, #{ code => 'NOT_IMPLEMENTED',