Handle Throwable in StandardMethodCodec (#18490)

diff --git a/shell/platform/android/io/flutter/plugin/common/MethodChannel.java b/shell/platform/android/io/flutter/plugin/common/MethodChannel.java
index 8c0bdd6..65ea239 100644
--- a/shell/platform/android/io/flutter/plugin/common/MethodChannel.java
+++ b/shell/platform/android/io/flutter/plugin/common/MethodChannel.java
@@ -165,7 +165,9 @@
     /**
      * Handles a successful result.
      *
-     * @param result The result, possibly null.
+     * @param result The result, possibly null. The result must be an Object type supported by the
+     *     codec. For instance, if you are using StandardCodec (default), please see {@link
+     *     StandardMessageCodec} documentation on what types are supported.
      */
     @UiThread
     void success(@Nullable Object result);
@@ -175,7 +177,9 @@
      *
      * @param errorCode An error code String.
      * @param errorMessage A human-readable error message String, possibly null.
-     * @param errorDetails Error details, possibly null
+     * @param errorDetails Error details, possibly null. The details must be an Object type
+     *     supported by the codec. For instance, if you are using StandardCodec (default), please
+     *     see {@link StandardMessageCodec} documentation on what types are supported.
      */
     @UiThread
     void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails);
diff --git a/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java b/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java
index 329d5dd..913001f 100644
--- a/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java
+++ b/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java
@@ -5,6 +5,9 @@
 package io.flutter.plugin.common;
 
 import io.flutter.plugin.common.StandardMessageCodec.ExposedByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
@@ -66,7 +69,11 @@
     stream.write(1);
     messageCodec.writeValue(stream, errorCode);
     messageCodec.writeValue(stream, errorMessage);
-    messageCodec.writeValue(stream, errorDetails);
+    if (errorDetails instanceof Throwable) {
+      messageCodec.writeValue(stream, getStackTrace((Throwable) errorDetails));
+    } else {
+      messageCodec.writeValue(stream, errorDetails);
+    }
     final ByteBuffer buffer = ByteBuffer.allocateDirect(stream.size());
     buffer.put(stream.buffer(), 0, stream.size());
     return buffer;
@@ -99,4 +106,10 @@
     }
     throw new IllegalArgumentException("Envelope corrupted");
   }
+
+  private static String getStackTrace(Throwable t) {
+    Writer result = new StringWriter();
+    t.printStackTrace(new PrintWriter(result));
+    return result.toString();
+  }
 }