aboutsummaryrefslogtreecommitdiffstats
path: root/lib/observer
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2017-04-25 17:44:55 +0200
committerSiri Hansen <[email protected]>2017-04-25 17:44:55 +0200
commit6e4620b7c07e55aa68812c8988e4a804e807e481 (patch)
tree0b3efc826e6eff93054f7dcbf67a81875d668d66 /lib/observer
parent61a20e55ccf6ff89a4863c1ed8754b8909646e88 (diff)
downloadotp-6e4620b7c07e55aa68812c8988e4a804e807e481.tar.gz
otp-6e4620b7c07e55aa68812c8988e4a804e807e481.tar.bz2
otp-6e4620b7c07e55aa68812c8988e4a804e807e481.zip
[observer] Don't crash if port info can not be fetched
When the observed node is older than OTP-19.0, observer_backend:get_port_list/1 does not exist. Observer would earliger crash in this situation. This is now corrected and a popup is displayed instead.
Diffstat (limited to 'lib/observer')
-rw-r--r--lib/observer/src/observer_port_wx.erl83
1 files changed, 63 insertions, 20 deletions
diff --git a/lib/observer/src/observer_port_wx.erl b/lib/observer/src/observer_port_wx.erl
index db5e6ceb38..1b83ea3fc5 100644
--- a/lib/observer/src/observer_port_wx.erl
+++ b/lib/observer/src/observer_port_wx.erl
@@ -69,7 +69,7 @@
parent,
grid,
panel,
- node=node(),
+ node={node(),true},
opt=#opt{},
right_clicked_port,
ports,
@@ -270,19 +270,39 @@ handle_cast(Event, _State) ->
error({unhandled_cast, Event}).
handle_info({portinfo_open, PortIdStr},
- State = #state{node=Node, grid=Grid, opt=Opt, open_wins=Opened}) ->
- Ports0 = get_ports(Node),
- Ports = update_grid(Grid, sel(State), Opt, Ports0),
- Port = lists:keyfind(PortIdStr, #port.id_str, Ports),
- NewOpened =
- case Port of
- false ->
- self() ! {error,"No such port: " ++ PortIdStr},
- Opened;
+ State = #state{node={ActiveNodeName,ActiveAvailable}, grid=Grid,
+ opt=Opt, open_wins=Opened}) ->
+ NodeName = node(list_to_port(PortIdStr)),
+ Available =
+ case NodeName of
+ ActiveNodeName ->
+ ActiveAvailable;
_ ->
- display_port_info(Grid, Port, Opened)
+ portinfo_available(NodeName)
end,
- {noreply, State#state{ports=Ports, open_wins=NewOpened}};
+ if Available ->
+ Ports0 = get_ports({NodeName,Available}),
+ Port = lists:keyfind(PortIdStr, #port.id_str, Ports0),
+ NewOpened =
+ case Port of
+ false ->
+ self() ! {error,"No such port: " ++ PortIdStr},
+ Opened;
+ _ ->
+ display_port_info(Grid, Port, Opened)
+ end,
+ Ports =
+ case NodeName of
+ ActiveNodeName ->
+ update_grid(Grid, sel(State), Opt, Ports0);
+ _ ->
+ State#state.ports
+ end,
+ {noreply, State#state{ports=Ports, open_wins=NewOpened}};
+ true ->
+ popup_unavailable_info(NodeName),
+ {noreply, State}
+ end;
handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt,
ports=OldPorts}) ->
@@ -295,19 +315,28 @@ handle_info(refresh_interval, State = #state{node=Node, grid=Grid, opt=Opt,
{noreply, State#state{ports=Ports}}
end;
-handle_info({active, Node}, State = #state{parent=Parent, grid=Grid, opt=Opt,
- timer=Timer0}) ->
- Ports0 = get_ports(Node),
+handle_info({active, NodeName}, State = #state{parent=Parent, grid=Grid, opt=Opt,
+ timer=Timer0}) ->
+ Available = portinfo_available(NodeName),
+ Available orelse popup_unavailable_info(NodeName),
+ Ports0 = get_ports({NodeName,Available}),
Ports = update_grid(Grid, sel(State), Opt, Ports0),
wxWindow:setFocus(Grid),
create_menus(Parent),
Timer = observer_lib:start_timer(Timer0, 10),
- {noreply, State#state{node=Node, ports=Ports, timer=Timer}};
+ {noreply, State#state{node={NodeName,Available}, ports=Ports, timer=Timer}};
handle_info(not_active, State = #state{timer = Timer0}) ->
Timer = observer_lib:stop_timer(Timer0),
{noreply, State#state{timer=Timer}};
+handle_info({info, {port_info_not_available,NodeName}},
+ State = #state{panel=Panel}) ->
+ Str = io_lib:format("Can not fetch port info from ~p.~n"
+ "Too old OTP version.",[NodeName]),
+ observer_lib:display_info_dialog(Panel, Str),
+ {noreply, State};
+
handle_info({error, Error}, #state{panel=Panel} = State) ->
Str = io_lib:format("ERROR: ~s~n",[Error]),
observer_lib:display_info_dialog(Panel, Str),
@@ -341,16 +370,18 @@ create_menus(Parent) ->
],
observer_wx:create_menus(Parent, MenuEntries).
-get_ports(Node) ->
- case get_ports2(Node) of
+get_ports({_NodeName,false}) ->
+ [];
+get_ports({NodeName,true}) ->
+ case get_ports2(NodeName) of
Error = {error, _} ->
self() ! Error,
[];
Res ->
Res
end.
-get_ports2(Node) ->
- case rpc:call(Node, observer_backend, get_port_list, []) of
+get_ports2(NodeName) ->
+ case rpc:call(NodeName, observer_backend, get_port_list, []) of
{badrpc, Error} ->
{error, Error};
Error = {error, _} ->
@@ -574,3 +605,15 @@ get_indecies(Rest = [_|_], I, [_|T]) ->
get_indecies(Rest, I+1, T);
get_indecies(_, _, _) ->
[].
+
+portinfo_available(NodeName) ->
+ _ = rpc:call(NodeName, code, ensure_loaded, [observer_backend]),
+ case rpc:call(NodeName, erlang, function_exported,
+ [observer_backend, get_port_list, 0]) of
+ true -> true;
+ false -> false
+ end.
+
+popup_unavailable_info(NodeName) ->
+ self() ! {info, {port_info_not_available, NodeName}},
+ ok.