Skip to content

Commit 6255037

Browse files
committed
[java] remove unused code from ErrorHandler
1 parent e8745c6 commit 6255037

File tree

7 files changed

+27
-726
lines changed

7 files changed

+27
-726
lines changed

java/src/org/openqa/selenium/remote/ErrorHandler.java

Lines changed: 4 additions & 303 deletions
Original file line numberDiff line numberDiff line change
@@ -17,66 +17,12 @@
1717

1818
package org.openqa.selenium.remote;
1919

20-
import java.lang.reflect.Constructor;
21-
import java.math.BigDecimal;
22-
import java.math.RoundingMode;
23-
import java.util.List;
24-
import java.util.Map;
25-
import java.util.Objects;
26-
import java.util.Optional;
27-
import java.util.function.Function;
28-
import org.openqa.selenium.UnhandledAlertException;
2920
import org.openqa.selenium.WebDriverException;
3021

31-
/** Maps exceptions to status codes for sending over the wire. */
22+
/** A helper to throw decoded exceptions. */
3223
public class ErrorHandler {
3324

34-
private static final String MESSAGE = "message";
35-
private static final String SCREEN_SHOT = "screen";
36-
private static final String CLASS = "class";
37-
private static final String STACK_TRACE = "stackTrace";
38-
private static final String LINE_NUMBER = "lineNumber";
39-
private static final String METHOD_NAME = "methodName";
40-
private static final String CLASS_NAME = "className";
41-
private static final String FILE_NAME = "fileName";
42-
private static final String UNKNOWN_CLASS = "<anonymous class>";
43-
private static final String UNKNOWN_METHOD = "<anonymous method>";
44-
private static final String UNKNOWN_FILE = null;
45-
46-
private final ErrorCodes errorCodes;
47-
48-
private boolean includeServerErrors;
49-
50-
public ErrorHandler() {
51-
this(true);
52-
}
53-
54-
/**
55-
* @param includeServerErrors Whether to include server-side details in thrown exceptions if the
56-
* information is available.
57-
*/
58-
public ErrorHandler(boolean includeServerErrors) {
59-
this.includeServerErrors = includeServerErrors;
60-
this.errorCodes = new ErrorCodes();
61-
}
62-
63-
/**
64-
* @param includeServerErrors Whether to include server-side details in thrown exceptions if the
65-
* information is available.
66-
* @param codes The ErrorCodes object to use for linking error codes to exceptions.
67-
*/
68-
public ErrorHandler(ErrorCodes codes, boolean includeServerErrors) {
69-
this.includeServerErrors = includeServerErrors;
70-
this.errorCodes = codes;
71-
}
72-
73-
public boolean isIncludeServerErrors() {
74-
return includeServerErrors;
75-
}
76-
77-
public void setIncludeServerErrors(boolean includeServerErrors) {
78-
this.includeServerErrors = includeServerErrors;
79-
}
25+
public ErrorHandler() {}
8026

8127
@SuppressWarnings("unchecked")
8228
public Response throwIfResponseFailed(Response response, long duration) throws RuntimeException {
@@ -92,254 +38,9 @@ public Response throwIfResponseFailed(Response response, long duration) throws R
9238
if (throwable instanceof RuntimeException) {
9339
throw (RuntimeException) throwable;
9440
}
95-
throw new RuntimeException(throwable);
41+
throw new WebDriverException(throwable);
9642
}
9743

98-
Class<? extends WebDriverException> outerErrorType =
99-
errorCodes.getExceptionType(response.getStatus());
100-
101-
Object value = response.getValue();
102-
String message = null;
103-
Throwable cause = null;
104-
105-
if (value instanceof Map) {
106-
Map<String, Object> rawErrorData = (Map<String, Object>) value;
107-
if (!rawErrorData.containsKey(MESSAGE) && rawErrorData.containsKey("value")) {
108-
try {
109-
rawErrorData = (Map<String, Object>) rawErrorData.get("value");
110-
} catch (ClassCastException cce) {
111-
message = String.valueOf(cce);
112-
}
113-
}
114-
try {
115-
message = (String) rawErrorData.get(MESSAGE);
116-
} catch (ClassCastException e) {
117-
// Ok, try to recover gracefully.
118-
message = String.valueOf(e);
119-
}
120-
121-
Throwable serverError = rebuildServerError(rawErrorData, response.getStatus());
122-
123-
// If serverError is null, then the server did not provide a className (only expected if
124-
// the server is a Java process) or a stack trace. The lack of a className is OK, but
125-
// not having a stacktrace really hurts our ability to debug problems.
126-
if (serverError == null) {
127-
if (includeServerErrors) {
128-
// TODO: this should probably link to a wiki article with more info.
129-
message += " (WARNING: The server did not provide any stacktrace information)";
130-
}
131-
} else if (!includeServerErrors) {
132-
// TODO: wiki article with more info.
133-
message += " (WARNING: The client has suppressed server-side stacktraces)";
134-
} else {
135-
cause = serverError;
136-
if (cause.getStackTrace() == null || cause.getStackTrace().length == 0) {
137-
message += " (WARNING: The server did not provide any stacktrace information)";
138-
}
139-
}
140-
141-
if (rawErrorData.get(SCREEN_SHOT) != null) {
142-
cause = new ScreenshotException(String.valueOf(rawErrorData.get(SCREEN_SHOT)), cause);
143-
}
144-
} else if (value != null) {
145-
message = String.valueOf(value);
146-
}
147-
148-
String duration1 = duration(duration);
149-
150-
if (message != null && !message.contains(duration1)) {
151-
message = message + duration1;
152-
}
153-
154-
WebDriverException toThrow = null;
155-
156-
if (outerErrorType.equals(UnhandledAlertException.class) && value instanceof Map) {
157-
toThrow = createUnhandledAlertException(value);
158-
}
159-
160-
if (toThrow == null) {
161-
toThrow =
162-
createThrowable(
163-
outerErrorType,
164-
new Class<?>[] {String.class, Throwable.class, Integer.class},
165-
new Object[] {message, cause, response.getStatus()});
166-
}
167-
168-
if (toThrow == null) {
169-
toThrow =
170-
createThrowable(
171-
outerErrorType,
172-
new Class<?>[] {String.class, Throwable.class},
173-
new Object[] {message, cause});
174-
}
175-
176-
if (toThrow == null) {
177-
toThrow =
178-
createThrowable(outerErrorType, new Class<?>[] {String.class}, new Object[] {message});
179-
}
180-
181-
if (toThrow == null) {
182-
toThrow = new WebDriverException(message, cause);
183-
}
184-
185-
throw toThrow;
186-
}
187-
188-
@SuppressWarnings("unchecked")
189-
private UnhandledAlertException createUnhandledAlertException(Object value) {
190-
Map<String, Object> rawErrorData = (Map<String, Object>) value;
191-
if (rawErrorData.containsKey("alert") || rawErrorData.containsKey("alertText")) {
192-
Object alertText = rawErrorData.get("alertText");
193-
if (alertText == null) {
194-
Map<String, Object> alert = (Map<String, Object>) rawErrorData.get("alert");
195-
if (alert != null) {
196-
alertText = alert.get("text");
197-
}
198-
}
199-
return createThrowable(
200-
UnhandledAlertException.class,
201-
new Class<?>[] {String.class, String.class},
202-
new Object[] {rawErrorData.get("message"), alertText});
203-
}
204-
return null;
205-
}
206-
207-
private String duration(long duration) {
208-
String prefix = "\nCommand duration or timeout: ";
209-
if (duration < 1000) {
210-
return prefix + duration + " milliseconds";
211-
}
212-
return prefix
213-
+ (new BigDecimal(duration).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_UP))
214-
+ " seconds";
215-
}
216-
217-
private <T extends Throwable> T createThrowable(
218-
Class<T> clazz, Class<?>[] parameterTypes, Object[] parameters) {
219-
try {
220-
Constructor<T> constructor = clazz.getConstructor(parameterTypes);
221-
return constructor.newInstance(parameters);
222-
} catch (OutOfMemoryError | ReflectiveOperationException e) {
223-
// Do nothing - fall through.
224-
}
225-
return null;
226-
}
227-
228-
private Throwable rebuildServerError(Map<String, Object> rawErrorData, int responseStatus) {
229-
230-
if (rawErrorData.get(CLASS) == null && rawErrorData.get(STACK_TRACE) == null) {
231-
// Not enough information for us to try to rebuild an error.
232-
return null;
233-
}
234-
235-
Throwable toReturn = null;
236-
String message = (String) rawErrorData.get(MESSAGE);
237-
Class<?> clazz = null;
238-
239-
// First: allow Remote Driver to specify the Selenium Server internal exception
240-
if (rawErrorData.get(CLASS) != null) {
241-
String className = (String) rawErrorData.get(CLASS);
242-
try {
243-
clazz = Class.forName(className);
244-
} catch (ClassNotFoundException ignored) {
245-
// Ok, fall-through
246-
}
247-
}
248-
249-
// If the above fails, map Response Status to Exception class
250-
if (null == clazz) {
251-
clazz = errorCodes.getExceptionType(responseStatus);
252-
}
253-
254-
if (clazz.equals(UnhandledAlertException.class)) {
255-
toReturn = createUnhandledAlertException(rawErrorData);
256-
} else if (Throwable.class.isAssignableFrom(clazz)) {
257-
@SuppressWarnings({"unchecked"})
258-
Class<? extends Throwable> throwableType = (Class<? extends Throwable>) clazz;
259-
toReturn =
260-
createThrowable(throwableType, new Class<?>[] {String.class}, new Object[] {message});
261-
}
262-
263-
if (toReturn == null) {
264-
toReturn = new UnknownServerException(message);
265-
}
266-
267-
// Note: if we have a class name above, we should always have a stack trace.
268-
// The inverse is not always true.
269-
StackTraceElement[] stackTrace = new StackTraceElement[0];
270-
if (rawErrorData.get(STACK_TRACE) != null) {
271-
@SuppressWarnings({"unchecked"})
272-
List<Map<String, Object>> stackTraceInfo =
273-
(List<Map<String, Object>>) rawErrorData.get(STACK_TRACE);
274-
275-
stackTrace =
276-
stackTraceInfo.stream()
277-
.map(entry -> new FrameInfoToStackFrame().apply(entry))
278-
.filter(Objects::nonNull)
279-
.toArray(StackTraceElement[]::new);
280-
}
281-
282-
toReturn.setStackTrace(stackTrace);
283-
return toReturn;
284-
}
285-
286-
/** Exception used as a place holder if the server returns an error without a stack trace. */
287-
public static class UnknownServerException extends WebDriverException {
288-
private UnknownServerException(String s) {
289-
super(s);
290-
}
291-
}
292-
293-
/**
294-
* Function that can rebuild a {@link StackTraceElement} from the frame info included with a
295-
* WebDriver JSON response.
296-
*/
297-
private static class FrameInfoToStackFrame
298-
implements Function<Map<String, Object>, StackTraceElement> {
299-
@Override
300-
public StackTraceElement apply(Map<String, Object> frameInfo) {
301-
if (frameInfo == null) {
302-
return null;
303-
}
304-
305-
Optional<Number> maybeLineNumberInteger = Optional.empty();
306-
307-
final Object lineNumberObject = frameInfo.get(LINE_NUMBER);
308-
if (lineNumberObject instanceof Number) {
309-
maybeLineNumberInteger = Optional.of((Number) lineNumberObject);
310-
} else if (lineNumberObject != null) {
311-
// might be a Number as a String
312-
try {
313-
maybeLineNumberInteger = Optional.of(Integer.parseInt(lineNumberObject.toString()));
314-
} catch (NumberFormatException e) {
315-
maybeLineNumberInteger = Optional.empty();
316-
}
317-
}
318-
319-
// default -1 for unknown, see StackTraceElement constructor javadoc
320-
final int lineNumber = maybeLineNumberInteger.orElse(-1).intValue();
321-
322-
// Gracefully handle remote servers that don't (or can't) send back
323-
// complete stack trace info. At least some of this information should
324-
// be included...
325-
String className =
326-
frameInfo.containsKey(CLASS_NAME)
327-
? toStringOrNull(frameInfo.get(CLASS_NAME))
328-
: UNKNOWN_CLASS;
329-
String methodName =
330-
frameInfo.containsKey(METHOD_NAME)
331-
? toStringOrNull(frameInfo.get(METHOD_NAME))
332-
: UNKNOWN_METHOD;
333-
String fileName =
334-
frameInfo.containsKey(FILE_NAME)
335-
? toStringOrNull(frameInfo.get(FILE_NAME))
336-
: UNKNOWN_FILE;
337-
338-
return new StackTraceElement(className, methodName, fileName, lineNumber);
339-
}
340-
341-
private static String toStringOrNull(Object o) {
342-
return o == null ? null : o.toString();
343-
}
44+
throw new WebDriverException("response failed with unknown status: " + response.getState());
34445
}
34546
}

java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.openqa.selenium.remote.codec.w3c;
1919

2020
import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY;
21-
import static java.net.HttpURLConnection.HTTP_BAD_METHOD;
2221
import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT;
2322
import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
2423
import static org.openqa.selenium.json.Json.MAP_TYPE;
@@ -88,15 +87,12 @@ public Response decode(HttpResponse encodedResponse) {
8887
// text"}
8988
if (!encodedResponse.isSuccessful()) {
9089
LOG.fine("Processing an error");
91-
if (HTTP_BAD_METHOD == encodedResponse.getStatus()) {
92-
response.setState("unknown command");
93-
response.setStatus(ErrorCodes.UNKNOWN_COMMAND);
94-
response.setValue(content);
95-
} else if (HTTP_GATEWAY_TIMEOUT == encodedResponse.getStatus()
90+
if (HTTP_GATEWAY_TIMEOUT == encodedResponse.getStatus()
9691
|| HTTP_BAD_GATEWAY == encodedResponse.getStatus()) {
9792
response.setState("unknown error");
9893
response.setStatus(ErrorCodes.UNHANDLED_ERROR);
99-
response.setValue(content);
94+
response.setValue(
95+
new WebDriverException("http gateway error: " + encodedResponse.getStatus()));
10096
} else {
10197
Map<String, Object> org = json.toType(content, MAP_TYPE);
10298
Map<String, Object> obj;

0 commit comments

Comments
 (0)