diff --git a/remote-robot/src/main/kotlin/com/intellij/remoterobot/RemoteRobot.kt b/remote-robot/src/main/kotlin/com/intellij/remoterobot/RemoteRobot.kt index 47bb6e4a..2f84fcfc 100644 --- a/remote-robot/src/main/kotlin/com/intellij/remoterobot/RemoteRobot.kt +++ b/remote-robot/src/main/kotlin/com/intellij/remoterobot/RemoteRobot.kt @@ -2,6 +2,7 @@ package com.intellij.remoterobot +import com.google.gson.GsonBuilder import com.intellij.remoterobot.client.IdeRobotApi import com.intellij.remoterobot.client.IdeRobotClient import com.intellij.remoterobot.data.RemoteComponent @@ -14,6 +15,7 @@ import com.intellij.remoterobot.fixtures.Fixture import com.intellij.remoterobot.search.Finder import com.intellij.remoterobot.search.locators.Locator import com.intellij.remoterobot.utils.DefaultHttpClient +import com.intellij.remoterobot.utils.ThrowableTypeAdapter import com.intellij.remoterobot.utils.waitFor import okhttp3.OkHttpClient import org.intellij.lang.annotations.Language @@ -28,15 +30,19 @@ import javax.imageio.ImageIO @DslMarker annotation class RemoteCommand - class RemoteRobot @JvmOverloads constructor( robotServerUrl: String, okHttpClient: OkHttpClient = DefaultHttpClient.client, secret: String? = null ) : SearchContext, JavaScriptApi, LambdaApi { + + private val gson = GsonBuilder() + .registerTypeAdapter(Throwable::class.java, ThrowableTypeAdapter) + .create() + override val ideRobotClient = IdeRobotClient( Retrofit.Builder().baseUrl(robotServerUrl) - .addConverterFactory(GsonConverterFactory.create()) + .addConverterFactory(GsonConverterFactory.create(gson)) .client(okHttpClient) .build() .create(IdeRobotApi::class.java) diff --git a/remote-robot/src/main/kotlin/com/intellij/remoterobot/utils/ThrowableTypeAdapter.kt b/remote-robot/src/main/kotlin/com/intellij/remoterobot/utils/ThrowableTypeAdapter.kt new file mode 100644 index 00000000..38c5e3bb --- /dev/null +++ b/remote-robot/src/main/kotlin/com/intellij/remoterobot/utils/ThrowableTypeAdapter.kt @@ -0,0 +1,36 @@ +package com.intellij.remoterobot.utils + +import com.google.gson.TypeAdapter +import com.google.gson.stream.JsonReader +import com.google.gson.stream.JsonWriter + +object ThrowableTypeAdapter : TypeAdapter() { + + override fun write(writer: JsonWriter, value: Throwable?) { + if (value == null) { + writer.nullValue() + return + } + writer.beginObject() + + // Include exception type name to give more context; for example, NullPointerException might + // not have a message + writer.name("type") + writer.value(value::class.java.getSimpleName()) + + writer.name("message") + writer.value(value.message) + + val cause = value.cause + if (cause != null) { + writer.name("cause") + write(writer, cause) + } + + writer.endObject() + } + + override fun read(reader: JsonReader): Throwable { + throw UnsupportedOperationException() + } +} \ No newline at end of file