1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
package com.vaadin.tests.rpclogger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.ErrorHandler;
import com.vaadin.server.ServerRpcMethodInvocation;
import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.communication.LegacyChangeVariablesInvocation;
import com.vaadin.shared.communication.MethodInvocation;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Button;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.v7.ui.ListSelect;
public class RPCLoggerUI extends AbstractTestUIWithLog implements ErrorHandler {
private List<Action> lastActions = new ArrayList<>();
public static class Action {
public Action(ClientConnector connector, MethodInvocation invocation) {
target = connector;
this.invocation = invocation;
}
private MethodInvocation invocation;
private ClientConnector target;
}
@Override
protected int getLogSize() {
return 10;
}
@Override
protected void setup(VaadinRequest request) {
setErrorHandler(this);
addComponent(new Button("Do something"));
ListSelect s = new ListSelect();
s.setMultiSelect(true);
s.addItem("foo");
s.addItem("bar");
addComponent(s);
addComponent(new Button("Action, which will fail", event -> {
throw new RuntimeException("Something went wrong");
}));
}
public void recordInvocation(ClientConnector connector,
LegacyChangeVariablesInvocation legacyInvocation) {
addAction(new Action(connector, legacyInvocation));
}
public void recordInvocation(ClientConnector connector,
ServerRpcMethodInvocation invocation) {
addAction(new Action(connector, invocation));
}
private void addAction(Action action) {
while (lastActions.size() >= 5) {
lastActions.remove(0);
}
lastActions.add(action);
}
public String formatAction(ClientConnector connector,
LegacyChangeVariablesInvocation legacyInvocation) {
String connectorIdentifier = getConnectorIdentifier(connector);
Map<String, Object> changes = legacyInvocation.getVariableChanges();
String rpcInfo = "";
for (String key : changes.keySet()) {
Object value = changes.get(key);
rpcInfo += key + ": " + formatValue(value);
}
return "Legacy RPC " + rpcInfo + " for " + connectorIdentifier;
}
public String formatAction(ClientConnector connector,
ServerRpcMethodInvocation invocation) {
String connectorIdentifier = getConnectorIdentifier(connector);
String rpcInfo = invocation.getInterfaceName() + "."
+ invocation.getMethodName() + " (";
for (Object o : invocation.getParameters()) {
rpcInfo += formatValue(o);
rpcInfo += ",";
}
rpcInfo = rpcInfo.substring(0, rpcInfo.length() - 2) + ")";
return "RPC " + rpcInfo + " for " + connectorIdentifier;
}
private String formatValue(Object value) {
if (value == null) {
return "null";
}
if (value instanceof String) {
return (String) value;
} else if (value instanceof Object[]) {
String formatted = "";
for (Object o : ((Object[]) value)) {
formatted += formatValue(o) + ",";
}
return formatted;
} else {
return value.toString();
}
}
private String getConnectorIdentifier(ClientConnector connector) {
String connectorIdentifier = connector.getClass().getSimpleName();
if (connector instanceof AbstractComponent) {
String caption = ((AbstractComponent) connector).getCaption();
if (caption != null) {
connectorIdentifier += " - " + caption;
}
}
return "'" + connectorIdentifier + "'";
}
@Override
public void error(com.vaadin.server.ErrorEvent event) {
String msg = "";
for (int i = 0; i < lastActions.size(); i++) {
Action action = lastActions.get(i);
if (action.invocation instanceof ServerRpcMethodInvocation) {
msg += "\n" + (i + 1) + " " + formatAction(action.target,
(ServerRpcMethodInvocation) action.invocation);
} else {
msg += "\n" + (i + 1) + " " + formatAction(action.target,
(LegacyChangeVariablesInvocation) action.invocation);
}
}
msg += "\n";
msg += "\n";
msg += "This error should not really be shown but logged for later analysis.";
Notification.show(
"Something went wrong. Actions leading up to this error were:",
msg, Type.ERROR_MESSAGE);
// log(msg);
}
}
|