[java] remove unused code from ErrorHandler
diff --git a/java/src/org/openqa/selenium/remote/ErrorHandler.java b/java/src/org/openqa/selenium/remote/ErrorHandler.java
index 59a52dd..86bc6ef 100644
--- a/java/src/org/openqa/selenium/remote/ErrorHandler.java
+++ b/java/src/org/openqa/selenium/remote/ErrorHandler.java
@@ -17,66 +17,12 @@
 
 package org.openqa.selenium.remote;
 
-import java.lang.reflect.Constructor;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.function.Function;
-import org.openqa.selenium.UnhandledAlertException;
 import org.openqa.selenium.WebDriverException;
 
-/** Maps exceptions to status codes for sending over the wire. */
+/** A helper to throw decoded exceptions. */
 public class ErrorHandler {
 
-  private static final String MESSAGE = "message";
-  private static final String SCREEN_SHOT = "screen";
-  private static final String CLASS = "class";
-  private static final String STACK_TRACE = "stackTrace";
-  private static final String LINE_NUMBER = "lineNumber";
-  private static final String METHOD_NAME = "methodName";
-  private static final String CLASS_NAME = "className";
-  private static final String FILE_NAME = "fileName";
-  private static final String UNKNOWN_CLASS = "<anonymous class>";
-  private static final String UNKNOWN_METHOD = "<anonymous method>";
-  private static final String UNKNOWN_FILE = null;
-
-  private final ErrorCodes errorCodes;
-
-  private boolean includeServerErrors;
-
-  public ErrorHandler() {
-    this(true);
-  }
-
-  /**
-   * @param includeServerErrors Whether to include server-side details in thrown exceptions if the
-   *     information is available.
-   */
-  public ErrorHandler(boolean includeServerErrors) {
-    this.includeServerErrors = includeServerErrors;
-    this.errorCodes = new ErrorCodes();
-  }
-
-  /**
-   * @param includeServerErrors Whether to include server-side details in thrown exceptions if the
-   *     information is available.
-   * @param codes The ErrorCodes object to use for linking error codes to exceptions.
-   */
-  public ErrorHandler(ErrorCodes codes, boolean includeServerErrors) {
-    this.includeServerErrors = includeServerErrors;
-    this.errorCodes = codes;
-  }
-
-  public boolean isIncludeServerErrors() {
-    return includeServerErrors;
-  }
-
-  public void setIncludeServerErrors(boolean includeServerErrors) {
-    this.includeServerErrors = includeServerErrors;
-  }
+  public ErrorHandler() {}
 
   @SuppressWarnings("unchecked")
   public Response throwIfResponseFailed(Response response, long duration) throws RuntimeException {
@@ -92,254 +38,9 @@ public Response throwIfResponseFailed(Response response, long duration) throws R
       if (throwable instanceof RuntimeException) {
         throw (RuntimeException) throwable;
       }
-      throw new RuntimeException(throwable);
+      throw new WebDriverException(throwable);
     }
 
-    Class<? extends WebDriverException> outerErrorType =
-        errorCodes.getExceptionType(response.getStatus());
-
-    Object value = response.getValue();
-    String message = null;
-    Throwable cause = null;
-
-    if (value instanceof Map) {
-      Map<String, Object> rawErrorData = (Map<String, Object>) value;
-      if (!rawErrorData.containsKey(MESSAGE) && rawErrorData.containsKey("value")) {
-        try {
-          rawErrorData = (Map<String, Object>) rawErrorData.get("value");
-        } catch (ClassCastException cce) {
-          message = String.valueOf(cce);
-        }
-      }
-      try {
-        message = (String) rawErrorData.get(MESSAGE);
-      } catch (ClassCastException e) {
-        // Ok, try to recover gracefully.
-        message = String.valueOf(e);
-      }
-
-      Throwable serverError = rebuildServerError(rawErrorData, response.getStatus());
-
-      // If serverError is null, then the server did not provide a className (only expected if
-      // the server is a Java process) or a stack trace. The lack of a className is OK, but
-      // not having a stacktrace really hurts our ability to debug problems.
-      if (serverError == null) {
-        if (includeServerErrors) {
-          // TODO: this should probably link to a wiki article with more info.
-          message += " (WARNING: The server did not provide any stacktrace information)";
-        }
-      } else if (!includeServerErrors) {
-        // TODO: wiki article with more info.
-        message += " (WARNING: The client has suppressed server-side stacktraces)";
-      } else {
-        cause = serverError;
-        if (cause.getStackTrace() == null || cause.getStackTrace().length == 0) {
-          message += " (WARNING: The server did not provide any stacktrace information)";
-        }
-      }
-
-      if (rawErrorData.get(SCREEN_SHOT) != null) {
-        cause = new ScreenshotException(String.valueOf(rawErrorData.get(SCREEN_SHOT)), cause);
-      }
-    } else if (value != null) {
-      message = String.valueOf(value);
-    }
-
-    String duration1 = duration(duration);
-
-    if (message != null && !message.contains(duration1)) {
-      message = message + duration1;
-    }
-
-    WebDriverException toThrow = null;
-
-    if (outerErrorType.equals(UnhandledAlertException.class) && value instanceof Map) {
-      toThrow = createUnhandledAlertException(value);
-    }
-
-    if (toThrow == null) {
-      toThrow =
-          createThrowable(
-              outerErrorType,
-              new Class<?>[] {String.class, Throwable.class, Integer.class},
-              new Object[] {message, cause, response.getStatus()});
-    }
-
-    if (toThrow == null) {
-      toThrow =
-          createThrowable(
-              outerErrorType,
-              new Class<?>[] {String.class, Throwable.class},
-              new Object[] {message, cause});
-    }
-
-    if (toThrow == null) {
-      toThrow =
-          createThrowable(outerErrorType, new Class<?>[] {String.class}, new Object[] {message});
-    }
-
-    if (toThrow == null) {
-      toThrow = new WebDriverException(message, cause);
-    }
-
-    throw toThrow;
-  }
-
-  @SuppressWarnings("unchecked")
-  private UnhandledAlertException createUnhandledAlertException(Object value) {
-    Map<String, Object> rawErrorData = (Map<String, Object>) value;
-    if (rawErrorData.containsKey("alert") || rawErrorData.containsKey("alertText")) {
-      Object alertText = rawErrorData.get("alertText");
-      if (alertText == null) {
-        Map<String, Object> alert = (Map<String, Object>) rawErrorData.get("alert");
-        if (alert != null) {
-          alertText = alert.get("text");
-        }
-      }
-      return createThrowable(
-          UnhandledAlertException.class,
-          new Class<?>[] {String.class, String.class},
-          new Object[] {rawErrorData.get("message"), alertText});
-    }
-    return null;
-  }
-
-  private String duration(long duration) {
-    String prefix = "\nCommand duration or timeout: ";
-    if (duration < 1000) {
-      return prefix + duration + " milliseconds";
-    }
-    return prefix
-        + (new BigDecimal(duration).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_UP))
-        + " seconds";
-  }
-
-  private <T extends Throwable> T createThrowable(
-      Class<T> clazz, Class<?>[] parameterTypes, Object[] parameters) {
-    try {
-      Constructor<T> constructor = clazz.getConstructor(parameterTypes);
-      return constructor.newInstance(parameters);
-    } catch (OutOfMemoryError | ReflectiveOperationException e) {
-      // Do nothing - fall through.
-    }
-    return null;
-  }
-
-  private Throwable rebuildServerError(Map<String, Object> rawErrorData, int responseStatus) {
-
-    if (rawErrorData.get(CLASS) == null && rawErrorData.get(STACK_TRACE) == null) {
-      // Not enough information for us to try to rebuild an error.
-      return null;
-    }
-
-    Throwable toReturn = null;
-    String message = (String) rawErrorData.get(MESSAGE);
-    Class<?> clazz = null;
-
-    // First: allow Remote Driver to specify the Selenium Server internal exception
-    if (rawErrorData.get(CLASS) != null) {
-      String className = (String) rawErrorData.get(CLASS);
-      try {
-        clazz = Class.forName(className);
-      } catch (ClassNotFoundException ignored) {
-        // Ok, fall-through
-      }
-    }
-
-    // If the above fails, map Response Status to Exception class
-    if (null == clazz) {
-      clazz = errorCodes.getExceptionType(responseStatus);
-    }
-
-    if (clazz.equals(UnhandledAlertException.class)) {
-      toReturn = createUnhandledAlertException(rawErrorData);
-    } else if (Throwable.class.isAssignableFrom(clazz)) {
-      @SuppressWarnings({"unchecked"})
-      Class<? extends Throwable> throwableType = (Class<? extends Throwable>) clazz;
-      toReturn =
-          createThrowable(throwableType, new Class<?>[] {String.class}, new Object[] {message});
-    }
-
-    if (toReturn == null) {
-      toReturn = new UnknownServerException(message);
-    }
-
-    // Note: if we have a class name above, we should always have a stack trace.
-    // The inverse is not always true.
-    StackTraceElement[] stackTrace = new StackTraceElement[0];
-    if (rawErrorData.get(STACK_TRACE) != null) {
-      @SuppressWarnings({"unchecked"})
-      List<Map<String, Object>> stackTraceInfo =
-          (List<Map<String, Object>>) rawErrorData.get(STACK_TRACE);
-
-      stackTrace =
-          stackTraceInfo.stream()
-              .map(entry -> new FrameInfoToStackFrame().apply(entry))
-              .filter(Objects::nonNull)
-              .toArray(StackTraceElement[]::new);
-    }
-
-    toReturn.setStackTrace(stackTrace);
-    return toReturn;
-  }
-
-  /** Exception used as a place holder if the server returns an error without a stack trace. */
-  public static class UnknownServerException extends WebDriverException {
-    private UnknownServerException(String s) {
-      super(s);
-    }
-  }
-
-  /**
-   * Function that can rebuild a {@link StackTraceElement} from the frame info included with a
-   * WebDriver JSON response.
-   */
-  private static class FrameInfoToStackFrame
-      implements Function<Map<String, Object>, StackTraceElement> {
-    @Override
-    public StackTraceElement apply(Map<String, Object> frameInfo) {
-      if (frameInfo == null) {
-        return null;
-      }
-
-      Optional<Number> maybeLineNumberInteger = Optional.empty();
-
-      final Object lineNumberObject = frameInfo.get(LINE_NUMBER);
-      if (lineNumberObject instanceof Number) {
-        maybeLineNumberInteger = Optional.of((Number) lineNumberObject);
-      } else if (lineNumberObject != null) {
-        // might be a Number as a String
-        try {
-          maybeLineNumberInteger = Optional.of(Integer.parseInt(lineNumberObject.toString()));
-        } catch (NumberFormatException e) {
-          maybeLineNumberInteger = Optional.empty();
-        }
-      }
-
-      // default -1 for unknown, see StackTraceElement constructor javadoc
-      final int lineNumber = maybeLineNumberInteger.orElse(-1).intValue();
-
-      // Gracefully handle remote servers that don't (or can't) send back
-      // complete stack trace info. At least some of this information should
-      // be included...
-      String className =
-          frameInfo.containsKey(CLASS_NAME)
-              ? toStringOrNull(frameInfo.get(CLASS_NAME))
-              : UNKNOWN_CLASS;
-      String methodName =
-          frameInfo.containsKey(METHOD_NAME)
-              ? toStringOrNull(frameInfo.get(METHOD_NAME))
-              : UNKNOWN_METHOD;
-      String fileName =
-          frameInfo.containsKey(FILE_NAME)
-              ? toStringOrNull(frameInfo.get(FILE_NAME))
-              : UNKNOWN_FILE;
-
-      return new StackTraceElement(className, methodName, fileName, lineNumber);
-    }
-
-    private static String toStringOrNull(Object o) {
-      return o == null ? null : o.toString();
-    }
+    throw new WebDriverException("response failed with unknown status: " + response.getState());
   }
 }
diff --git a/java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java b/java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java
index 33cbf8a..e97d685 100644
--- a/java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java
+++ b/java/src/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodec.java
@@ -18,7 +18,6 @@
 package org.openqa.selenium.remote.codec.w3c;
 
 import static java.net.HttpURLConnection.HTTP_BAD_GATEWAY;
-import static java.net.HttpURLConnection.HTTP_BAD_METHOD;
 import static java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT;
 import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
 import static org.openqa.selenium.json.Json.MAP_TYPE;
@@ -88,15 +87,12 @@ public Response decode(HttpResponse encodedResponse) {
     // text"}
     if (!encodedResponse.isSuccessful()) {
       LOG.fine("Processing an error");
-      if (HTTP_BAD_METHOD == encodedResponse.getStatus()) {
-        response.setState("unknown command");
-        response.setStatus(ErrorCodes.UNKNOWN_COMMAND);
-        response.setValue(content);
-      } else if (HTTP_GATEWAY_TIMEOUT == encodedResponse.getStatus()
+      if (HTTP_GATEWAY_TIMEOUT == encodedResponse.getStatus()
           || HTTP_BAD_GATEWAY == encodedResponse.getStatus()) {
         response.setState("unknown error");
         response.setStatus(ErrorCodes.UNHANDLED_ERROR);
-        response.setValue(content);
+        response.setValue(
+            new WebDriverException("http gateway error: " + encodedResponse.getStatus()));
       } else {
         Map<String, Object> org = json.toType(content, MAP_TYPE);
         Map<String, Object> obj;
diff --git a/java/test/org/openqa/selenium/remote/ErrorHandlerTest.java b/java/test/org/openqa/selenium/remote/ErrorHandlerTest.java
index c4e9e18..034aa3c 100644
--- a/java/test/org/openqa/selenium/remote/ErrorHandlerTest.java
+++ b/java/test/org/openqa/selenium/remote/ErrorHandlerTest.java
@@ -20,31 +20,11 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 
-import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
-import org.openqa.selenium.InvalidCookieDomainException;
-import org.openqa.selenium.InvalidElementStateException;
-import org.openqa.selenium.InvalidSelectorException;
-import org.openqa.selenium.JavascriptException;
-import org.openqa.selenium.NoAlertPresentException;
-import org.openqa.selenium.NoSuchElementException;
-import org.openqa.selenium.NoSuchFrameException;
-import org.openqa.selenium.NoSuchSessionException;
-import org.openqa.selenium.NoSuchWindowException;
-import org.openqa.selenium.ScriptTimeoutException;
-import org.openqa.selenium.SessionNotCreatedException;
-import org.openqa.selenium.StaleElementReferenceException;
-import org.openqa.selenium.TimeoutException;
-import org.openqa.selenium.UnableToSetCookieException;
-import org.openqa.selenium.UnhandledAlertException;
-import org.openqa.selenium.UnsupportedCommandException;
 import org.openqa.selenium.WebDriverException;
-import org.openqa.selenium.interactions.MoveTargetOutOfBoundsException;
 import org.openqa.selenium.json.Json;
 
 @Tag("UnitTests")
@@ -71,416 +51,38 @@ private static Map<String, Object> toMap(Object o) {
   @BeforeEach
   public void setUp() {
     handler = new ErrorHandler();
-    handler.setIncludeServerErrors(true);
   }
 
   @Test
   void testShouldNotThrowIfResponseWasASuccess() {
-    handler.throwIfResponseFailed(createResponse(ErrorCodes.SUCCESS), 100);
+    handler.throwIfResponseFailed(createResponse("success"), 100);
     // All is well if this doesn't throw.
   }
 
   @Test
-  void testThrowsCorrectExceptionTypes() {
-    assertThrowsCorrectExceptionType(ErrorCodes.NO_SUCH_WINDOW, NoSuchWindowException.class);
-    assertThrowsCorrectExceptionType(ErrorCodes.NO_SUCH_FRAME, NoSuchFrameException.class);
-    assertThrowsCorrectExceptionType(ErrorCodes.NO_SUCH_ELEMENT, NoSuchElementException.class);
-    assertThrowsCorrectExceptionType(ErrorCodes.UNKNOWN_COMMAND, UnsupportedCommandException.class);
-    assertThrowsCorrectExceptionType(
-        ErrorCodes.METHOD_NOT_ALLOWED, UnsupportedCommandException.class);
-    assertThrowsCorrectExceptionType(
-        ErrorCodes.STALE_ELEMENT_REFERENCE, StaleElementReferenceException.class);
-    assertThrowsCorrectExceptionType(
-        ErrorCodes.INVALID_ELEMENT_STATE, InvalidElementStateException.class);
-    assertThrowsCorrectExceptionType(ErrorCodes.XPATH_LOOKUP_ERROR, InvalidSelectorException.class);
-  }
-
-  private void assertThrowsCorrectExceptionType(
-      int status, Class<? extends RuntimeException> type) {
-    assertThatExceptionOfType(RuntimeException.class)
-        .isThrownBy(() -> handler.throwIfResponseFailed(createResponse(status), 123))
-        .satisfies(e -> assertThat(type.isAssignableFrom(e.getClass())).isTrue());
+  void testShouldThrowIfResponseWasNotSuccess() {
+    Response response = createResponse("other");
+    assertThatExceptionOfType(WebDriverException.class)
+        .isThrownBy(() -> handler.throwIfResponseFailed(response, 123))
+        .withNoCause();
   }
 
   @Test
   void testShouldThrowAVanillaWebDriverExceptionIfServerDoesNotProvideAValue() {
-    Response response = createResponse(ErrorCodes.UNHANDLED_ERROR);
+    Response response = createResponse("unknown error");
     assertThatExceptionOfType(WebDriverException.class)
         .isThrownBy(() -> handler.throwIfResponseFailed(response, 123))
         .withNoCause()
         .withMessageContaining(new WebDriverException().getMessage());
   }
 
-  @Test
-  void testShouldNotSetCauseIfResponseValueIsJustAString() {
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, "boom"), 123))
-        .withNoCause()
-        .satisfies(expected -> assertThat(expected).isExactlyInstanceOf(WebDriverException.class))
-        .withMessageContaining("boom")
-        .withMessageContaining(new WebDriverException().getMessage());
+  private Response createResponse(String state) {
+    return createResponse(state, null);
   }
 
-  @Test
-  void testCauseShouldBeAnUnknownServerExceptionIfServerOnlyReturnsAMessage() {
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, ImmutableMap.of("message", "boom")),
-                    123))
-        .withNoCause()
-        .withMessageContaining("boom")
-        .withMessageContaining(new WebDriverException().getMessage());
-  }
-
-  @Test
-  void testCauseShouldUseTheNamedClassIfAvailableOnTheClassPath() {
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(
-                        ErrorCodes.UNHANDLED_ERROR,
-                        ImmutableMap.of(
-                            "message", "boom", "class", NullPointerException.class.getName())),
-                    123))
-        .withMessage(
-            new WebDriverException(
-                    "boom (WARNING: The server did not provide any stacktrace information)\n"
-                        + "Command duration or timeout: 123 milliseconds")
-                .getMessage())
-        .withCauseInstanceOf(NullPointerException.class)
-        .satisfies(expected -> assertThat(expected.getCause()).hasMessage("boom"));
-  }
-
-  @Test
-  void testCauseStackTraceShouldBeEmptyIfTheServerDidNotProvideThatInformation() {
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(
-                        ErrorCodes.UNHANDLED_ERROR,
-                        ImmutableMap.of(
-                            "message", "boom", "class", NullPointerException.class.getName())),
-                    1234))
-        .withMessage(
-            new WebDriverException(
-                    "boom (WARNING: The server did not provide any stacktrace information)\n"
-                        + "Command duration or timeout: 1.23 seconds")
-                .getMessage())
-        .withCauseInstanceOf(NullPointerException.class)
-        .satisfies(
-            expected -> {
-              assertThat(expected.getCause()).hasMessage("boom");
-              assertThat(expected.getCause().getStackTrace()).isEmpty();
-            });
-  }
-
-  @Test
-  void testShouldBeAbleToRebuildASerializedException() {
-    RuntimeException serverError =
-        new RuntimeException("foo bar baz!\nCommand duration or timeout: 123 milliseconds");
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, toMap(serverError)), 123))
-        .withMessage(new WebDriverException(serverError.getMessage()).getMessage())
-        .withCauseInstanceOf(serverError.getClass())
-        .satisfies(
-            expected -> {
-              assertThat(expected.getCause().getMessage()).isEqualTo(serverError.getMessage());
-              assertStackTracesEqual(
-                  expected.getCause().getStackTrace(), serverError.getStackTrace());
-            });
-  }
-
-  @Test
-  void testShouldDefaultToWebDriverExceptionIfClassIsNotSpecified() {
-    RuntimeException serverError = new RuntimeException("foo bar baz!");
-    Map<String, Object> data = toMap(serverError);
-    data.remove("class");
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, data), 123))
-        .withMessage(
-            new WebDriverException(
-                    serverError.getMessage() + "\nCommand duration or timeout: 123 milliseconds",
-                    new WebDriverException())
-                .getMessage())
-        .withCauseInstanceOf(WebDriverException.class)
-        .satisfies(
-            expected -> {
-              Throwable cause = expected.getCause();
-              assertThat(cause.getMessage())
-                  .isEqualTo(new WebDriverException(serverError.getMessage()).getMessage());
-              assertStackTracesEqual(serverError.getStackTrace(), cause.getStackTrace());
-            });
-  }
-
-  @Test
-  void testShouldStillTryToBuildWebDriverExceptionIfClassIsNotProvidedAndStackTraceIsNotForJava() {
-    Map<String, ?> data =
-        ImmutableMap.of(
-            "message",
-            "some error message",
-            "stackTrace",
-            Collections.singletonList(
-                ImmutableMap.of(
-                    "lineNumber", 1224,
-                    "methodName", "someMethod",
-                    "className", "MyClass",
-                    "fileName", "Resource.m")));
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, data), 123))
-        .withMessage(
-            new WebDriverException(
-                    "some error message\nCommand duration or timeout: 123 milliseconds",
-                    new WebDriverException())
-                .getMessage())
-        .withCauseInstanceOf(WebDriverException.class)
-        .satisfies(
-            expected -> {
-              StackTraceElement[] expectedTrace = {
-                new StackTraceElement("MyClass", "someMethod", "Resource.m", 1224)
-              };
-              WebDriverException helper = new WebDriverException("some error message");
-              helper.setStackTrace(expectedTrace);
-
-              Throwable cause = expected.getCause();
-              assertThat(cause.getMessage()).isEqualTo(helper.getMessage());
-              assertStackTracesEqual(expectedTrace, cause.getStackTrace());
-            });
-  }
-
-  @Test
-  void testShouldNotBuildWebDriverExceptionIfClassAndStackTraceIsNull() {
-    Map<String, Object> data = new HashMap<>();
-    data.put("message", "some error message");
-    data.put("class", null);
-    data.put("stackTrace", null);
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, data), 123))
-        .withMessageStartingWith(
-            new WebDriverException(
-                    "some error message (WARNING: The server did not provide any stacktrace"
-                        + " information)\n"
-                        + "Command duration or timeout: 123 milliseconds",
-                    new WebDriverException())
-                .getMessage());
-  }
-
-  @Test
-  void testShouldNotBuildWebDriverExceptionIfClassNullAndStackTraceNotNull() {
-    Map<String, Object> data = new HashMap<>();
-    data.put("message", "some error message");
-    data.put("class", null);
-    data.put(
-        "stackTrace",
-        Collections.singletonList(
-            ImmutableMap.of(
-                "lineNumber", 1224,
-                "methodName", "someMethod",
-                "className", "MyClass",
-                "fileName", "Resource.m")));
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, data), 123))
-        .withMessageStartingWith(
-            new WebDriverException(
-                    "some error message\nCommand duration or timeout: 123 milliseconds",
-                    new WebDriverException())
-                .getMessage());
-  }
-
-  @Test
-  void testShouldNotBuildWebDriverExceptionIfClassNotNullAndStackTraceNull() {
-    Map<String, Object> data = new HashMap<>();
-    data.put("message", "some error message");
-    data.put("class", "a");
-    data.put("stackTrace", null);
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, data), 123))
-        .withMessageStartingWith(
-            new WebDriverException(
-                    "some error message (WARNING: The server did not provide any stacktrace"
-                        + " information)\n"
-                        + "Command duration or timeout: 123 milliseconds",
-                    new WebDriverException())
-                .getMessage());
-  }
-
-  @Test
-  void testToleratesNonNumericLineNumber() {
-    Map<String, ?> data =
-        ImmutableMap.of(
-            "message",
-            "some error message",
-            "stackTrace",
-            Collections.singletonList(
-                ImmutableMap.of(
-                    "lineNumber", "some string, might be empty or 'Not available'",
-                    "methodName", "someMethod",
-                    "className", "MyClass",
-                    "fileName", "Resource.m")));
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, data), 123))
-        .withMessage(
-            new WebDriverException(
-                    "some error message\nCommand duration or timeout: 123 milliseconds",
-                    new WebDriverException())
-                .getMessage())
-        .withCauseInstanceOf(WebDriverException.class)
-        .satisfies(
-            expected -> {
-              StackTraceElement[] expectedTrace = {
-                new StackTraceElement("MyClass", "someMethod", "Resource.m", -1)
-              };
-              WebDriverException helper = new WebDriverException("some error message");
-              helper.setStackTrace(expectedTrace);
-
-              Throwable cause = expected.getCause();
-              assertThat(cause.getMessage()).isEqualTo(helper.getMessage());
-              assertStackTracesEqual(expectedTrace, cause.getStackTrace());
-            });
-  }
-
-  @Test
-  void testToleratesNumericLineNumberAsString() {
-    Map<String, ?> data =
-        ImmutableMap.of(
-            "message",
-            "some error message",
-            "stackTrace",
-            Collections.singletonList(
-                ImmutableMap.of(
-                    "lineNumber", "1224", // number as a string
-                    "methodName", "someMethod",
-                    "className", "MyClass",
-                    "fileName", "Resource.m")));
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, data), 123))
-        .withMessage(
-            new WebDriverException(
-                    "some error message\nCommand duration or timeout: 123 milliseconds",
-                    new WebDriverException())
-                .getMessage())
-        .withCauseInstanceOf(WebDriverException.class)
-        .satisfies(
-            expected -> {
-              StackTraceElement[] expectedTrace = {
-                new StackTraceElement("MyClass", "someMethod", "Resource.m", 1224)
-              };
-              WebDriverException helper = new WebDriverException("some error message");
-              helper.setStackTrace(expectedTrace);
-
-              Throwable cause = expected.getCause();
-              assertThat(cause.getMessage()).isEqualTo(helper.getMessage());
-
-              assertStackTracesEqual(expectedTrace, cause.getStackTrace());
-            });
-  }
-
-  @Test
-  void testShouldIndicateWhenTheServerReturnedAnExceptionThatWasSuppressed() {
-    RuntimeException serverError = new RuntimeException("foo bar baz!");
-
-    handler.setIncludeServerErrors(false);
-
-    assertThatExceptionOfType(WebDriverException.class)
-        .isThrownBy(
-            () ->
-                handler.throwIfResponseFailed(
-                    createResponse(ErrorCodes.UNHANDLED_ERROR, toMap(serverError)), 123))
-        .withNoCause()
-        .withMessageContaining(serverError.getMessage())
-        .withMessageContaining(new WebDriverException().getMessage());
-  }
-
-  @Test
-  void testStatusCodesRaisedBackToStatusMatches() {
-    Map<Integer, Class<?>> exceptions = new HashMap<>();
-    exceptions.put(ErrorCodes.NO_SUCH_SESSION, NoSuchSessionException.class);
-    exceptions.put(ErrorCodes.NO_SUCH_ELEMENT, NoSuchElementException.class);
-    exceptions.put(ErrorCodes.NO_SUCH_FRAME, NoSuchFrameException.class);
-    exceptions.put(ErrorCodes.UNKNOWN_COMMAND, UnsupportedCommandException.class);
-    exceptions.put(ErrorCodes.STALE_ELEMENT_REFERENCE, StaleElementReferenceException.class);
-    exceptions.put(ErrorCodes.INVALID_ELEMENT_STATE, InvalidElementStateException.class);
-    exceptions.put(ErrorCodes.UNHANDLED_ERROR, WebDriverException.class);
-    exceptions.put(ErrorCodes.JAVASCRIPT_ERROR, JavascriptException.class);
-    exceptions.put(ErrorCodes.XPATH_LOOKUP_ERROR, InvalidSelectorException.class);
-    exceptions.put(ErrorCodes.TIMEOUT, TimeoutException.class);
-    exceptions.put(ErrorCodes.NO_SUCH_WINDOW, NoSuchWindowException.class);
-    exceptions.put(ErrorCodes.INVALID_COOKIE_DOMAIN, InvalidCookieDomainException.class);
-    exceptions.put(ErrorCodes.UNABLE_TO_SET_COOKIE, UnableToSetCookieException.class);
-    exceptions.put(ErrorCodes.UNEXPECTED_ALERT_PRESENT, UnhandledAlertException.class);
-    exceptions.put(ErrorCodes.NO_ALERT_PRESENT, NoAlertPresentException.class);
-    exceptions.put(ErrorCodes.ASYNC_SCRIPT_TIMEOUT, ScriptTimeoutException.class);
-    exceptions.put(ErrorCodes.INVALID_SELECTOR_ERROR, InvalidSelectorException.class);
-    exceptions.put(ErrorCodes.SESSION_NOT_CREATED, SessionNotCreatedException.class);
-    exceptions.put(ErrorCodes.MOVE_TARGET_OUT_OF_BOUNDS, MoveTargetOutOfBoundsException.class);
-    exceptions.put(ErrorCodes.INVALID_XPATH_SELECTOR, InvalidSelectorException.class);
-    exceptions.put(ErrorCodes.INVALID_XPATH_SELECTOR_RETURN_TYPER, InvalidSelectorException.class);
-
-    for (Map.Entry<Integer, Class<?>> exception : exceptions.entrySet()) {
-      assertThatExceptionOfType(WebDriverException.class)
-          .isThrownBy(() -> handler.throwIfResponseFailed(createResponse(exception.getKey()), 123))
-          .satisfies(
-              e -> {
-                assertThat(e.getClass().getSimpleName())
-                    .isEqualTo(exception.getValue().getSimpleName());
-
-                // all of the special invalid selector exceptions are just mapped to the generic
-                // invalid selector
-                int expected =
-                    e instanceof InvalidSelectorException
-                        ? ErrorCodes.INVALID_SELECTOR_ERROR
-                        : exception.getKey();
-                assertThat(new ErrorCodes().toStatusCode(e)).isEqualTo(expected);
-              });
-    }
-  }
-
-  private Response createResponse(int status) {
-    return createResponse(status, null);
-  }
-
-  private Response createResponse(int status, Object value) {
+  private Response createResponse(String state, Object value) {
     Response response = new Response();
-    response.setStatus(status);
-    response.setState(new ErrorCodes().toState(status));
+    response.setState(state);
     response.setValue(value);
     return response;
   }
diff --git a/java/test/org/openqa/selenium/remote/RemotableByTest.java b/java/test/org/openqa/selenium/remote/RemotableByTest.java
index df526e4..39b5e60 100644
--- a/java/test/org/openqa/selenium/remote/RemotableByTest.java
+++ b/java/test/org/openqa/selenium/remote/RemotableByTest.java
@@ -206,9 +206,11 @@ private Response createResponse(Object value) {
 
   private Response createError(Exception e) {
     Response res = new Response();
-    res.setStatus(errorCodes.toStatusCode(e));
-    res.setState(errorCodes.toState(res.getStatus()));
-    res.setValue(ErrorCodec.createDefault().encode(e));
+    var encoded = ErrorCodec.createDefault().encode(e);
+    @SuppressWarnings("unchecked")
+    Map<String, Object> map = (Map<String, Object>) encoded.get("value");
+    res.setState(map.get("error").toString());
+    res.setValue(e);
     return res;
   }
 
diff --git a/java/test/org/openqa/selenium/remote/RemoteWebDriverUnitTest.java b/java/test/org/openqa/selenium/remote/RemoteWebDriverUnitTest.java
index baf7143..eb5bbfc 100644
--- a/java/test/org/openqa/selenium/remote/RemoteWebDriverUnitTest.java
+++ b/java/test/org/openqa/selenium/remote/RemoteWebDriverUnitTest.java
@@ -792,7 +792,7 @@ void canHandleResponseWithErrorCodeButNoExceptionReturnedByCommandExecutor() {
 
     assertThatExceptionOfType(WebDriverException.class)
         .isThrownBy(fixture.driver::getCurrentUrl)
-        .withMessageStartingWith("BOOM!!!")
+        .withMessageStartingWith("response failed with unknown status: element click intercepted")
         .withMessageContaining("Build info: ")
         .withMessageContaining("Driver info: org.openqa.selenium.remote.RemoteWebDriver")
         .withMessageContaining(String.format("Session ID: %s", fixture.driver.getSessionId()))
diff --git a/java/test/org/openqa/selenium/remote/RemoteWebElementTest.java b/java/test/org/openqa/selenium/remote/RemoteWebElementTest.java
index d593c44..902ca85 100644
--- a/java/test/org/openqa/selenium/remote/RemoteWebElementTest.java
+++ b/java/test/org/openqa/selenium/remote/RemoteWebElementTest.java
@@ -165,7 +165,7 @@ void canHandleResponseWithErrorCodeButNoExceptionReturnedByCommandExecutor() {
 
     assertThatExceptionOfType(WebDriverException.class)
         .isThrownBy(fixture.element::click)
-        .withMessageStartingWith("BOOM!!!")
+        .withMessageStartingWith("response failed with unknown status: element click intercepted")
         .withMessageContaining("Build info: ")
         .withMessageContaining("Driver info: org.openqa.selenium.remote.RemoteWebDriver")
         .withMessageContaining(String.format("Session ID: %s", fixture.driver.getSessionId()))
diff --git a/java/test/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodecTest.java b/java/test/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodecTest.java
index b7d1e84..343b274 100644
--- a/java/test/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodecTest.java
+++ b/java/test/org/openqa/selenium/remote/codec/w3c/W3CHttpResponseCodecTest.java
@@ -79,7 +79,7 @@ void shouldBeAbleToHandleGatewayTimeoutError() {
     Response decoded = new W3CHttpResponseCodec().decode(response);
 
     assertThat(decoded.getStatus()).isEqualTo(ErrorCodes.UNHANDLED_ERROR);
-    assertThat(decoded.getValue()).isEqualTo(responseString);
+    assertThat(decoded.getValue()).isInstanceOf(WebDriverException.class);
   }
 
   @Test
@@ -105,7 +105,7 @@ void shouldBeAbleToHandleBadGatewayError() {
     Response decoded = new W3CHttpResponseCodec().decode(response);
 
     assertThat(decoded.getStatus()).isEqualTo(ErrorCodes.UNHANDLED_ERROR);
-    assertThat(decoded.getValue()).isEqualTo(responseString);
+    assertThat(decoded.getValue()).isInstanceOf(WebDriverException.class);
   }
 
   @Test