Skip to content

Commit b695c84

Browse files
committed
wrap the json error with Error classes
1 parent 6a9b300 commit b695c84

File tree

7 files changed

+98
-11
lines changed

7 files changed

+98
-11
lines changed

build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ dependencies {
2222
implementation("com.google.code.gson:gson:2.10.1")
2323

2424
testImplementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
25+
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
2526
}
2627

2728
java {
@@ -43,6 +44,10 @@ tasks {
4344
}
4445
}
4546

47+
tasks.test {
48+
useJUnitPlatform()
49+
}
50+
4651
// Create javadocJar and sourcesJar tasks
4752
val javadocJar by tasks.registering(Jar::class) {
4853
archiveClassifier.set("javadoc")

src/main/kotlin/com/cjcrafter/openai/chat/ChatBot.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package com.cjcrafter.openai.chat
22

3+
import com.cjcrafter.openai.exception.OpenAIError
34
import com.google.gson.*
45
import okhttp3.*
56
import okhttp3.MediaType.Companion.toMediaType
6-
import okhttp3.OkHttpClient.Builder
77
import okhttp3.RequestBody.Companion.toRequestBody
88
import java.io.IOException
9-
import java.lang.IllegalArgumentException
10-
import java.util.concurrent.TimeUnit
119
import java.util.function.Consumer
1210

1311
/**
@@ -62,8 +60,6 @@ class ChatBot @JvmOverloads constructor(
6260
*
6361
* @param request The input information for ChatGPT.
6462
* @return The returned response.
65-
* @throws IOException If an IO Exception occurs.
66-
* @throws IllegalArgumentException If the input arguments are invalid.
6763
*/
6864
@Throws(IOException::class)
6965
fun generateResponse(request: ChatRequest): ChatResponse {
@@ -75,13 +71,14 @@ class ChatBot @JvmOverloads constructor(
7571
try {
7672
client.newCall(httpRequest).execute().use { response ->
7773

78-
// Servers respond to API calls with json blocks. Since raw JSON isn't
79-
// very developer friendly, we wrap for easy data access.
8074
rootObject = JsonParser.parseString(response.body!!.string()).asJsonObject
81-
require(!rootObject!!.has("error")) { rootObject!!.get("error").asJsonObject["message"].asString }
75+
if (rootObject!!.has("error"))
76+
throw OpenAIError.fromJson(rootObject!!["error"].asJsonObject)
77+
8278
return ChatResponse(rootObject!!)
8379
}
8480
} catch (ex: Throwable) {
81+
println(rootObject)
8582
throw ex
8683
}
8784
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.cjcrafter.openai.exception
2+
3+
import com.google.gson.JsonElement
4+
5+
class InvalidRequestError(param: JsonElement?, code: String?, message: String) : OpenAIError(param, code, message)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.cjcrafter.openai.exception
2+
3+
import com.google.gson.JsonElement
4+
import com.google.gson.JsonObject
5+
6+
// TODO docs
7+
abstract class OpenAIError : Exception {
8+
9+
val param: JsonElement?
10+
val code: String?
11+
12+
constructor(param: JsonElement?, code: String?, message: String) : super(message) {
13+
this.param = param
14+
this.code = code
15+
}
16+
constructor(param: JsonElement?, code: String?, message: String, cause: Throwable?) : super(message, cause) {
17+
this.param = param
18+
this.code = code
19+
}
20+
constructor(param: JsonElement?, code: String?, cause: Throwable?) : super(cause) {
21+
this.param = param
22+
this.code = code
23+
}
24+
25+
companion object {
26+
27+
@JvmStatic
28+
fun fromJson(json: JsonObject) : OpenAIError {
29+
val message = json["message"].asString
30+
val type = json["type"].asString
31+
val param = json["param"]
32+
val code = json["code"].asString
33+
34+
// TODO add more error types
35+
return when (json["type"].asString) {
36+
"invalid_request_error" -> InvalidRequestError(param, code, message)
37+
else -> UnknownError(param, code, message, type)
38+
}
39+
}
40+
}
41+
}

src/main/kotlin/com/cjcrafter/openai/exception/OpenAIException.kt

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.cjcrafter.openai.exception
2+
3+
import com.google.gson.JsonElement
4+
5+
class UnknownError(param: JsonElement?, code: String?, message: String, val type: String?) : OpenAIError(param, code, message)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.cjcrafter.openai;
2+
3+
import com.cjcrafter.openai.chat.*;
4+
import io.github.cdimascio.dotenv.Dotenv;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
10+
import static org.junit.jupiter.api.Assertions.*;
11+
12+
public class ExceptionTests {
13+
14+
@Test
15+
void test_invalidModel() {
16+
String key = Dotenv.load().get("OPENAI_TOKEN");
17+
18+
String initialPrompt = "Just say hi";
19+
List<ChatMessage> messages = new ArrayList<>(List.of(new ChatMessage(ChatUser.SYSTEM, initialPrompt)));
20+
ChatRequest request = new ChatRequest("gpt-238974-invalid-model", messages);
21+
ChatBot bot = new ChatBot(key);
22+
23+
assertThrows(Throwable.class, () -> bot.generateResponse(request));
24+
}
25+
26+
@Test
27+
void test_invalidToken() {
28+
String key = "sk-Thisisaninvalidtoken";
29+
30+
String initialPrompt = "Just say hi";
31+
List<ChatMessage> messages = new ArrayList<>(List.of(new ChatMessage(ChatUser.SYSTEM, initialPrompt)));
32+
ChatRequest request = new ChatRequest("gpt-3.5-turbo", messages);
33+
ChatBot bot = new ChatBot(key);
34+
35+
assertThrows(Throwable.class, () -> bot.generateResponse(request));
36+
}
37+
}

0 commit comments

Comments
 (0)