diff --git a/LavalinkServer/src/main/java/lavalink/server/player/EventEmitter.kt b/LavalinkServer/src/main/java/lavalink/server/player/EventEmitter.kt index 9630481ea..dd425500c 100644 --- a/LavalinkServer/src/main/java/lavalink/server/player/EventEmitter.kt +++ b/LavalinkServer/src/main/java/lavalink/server/player/EventEmitter.kt @@ -76,12 +76,14 @@ class EventEmitter( // These exceptions are already logged by Lavaplayer override fun onTrackException(player: AudioPlayer, track: AudioTrack, exception: FriendlyException) { + val rootCause = getRootCause(exception) + this.player.socketContext.sendMessage( Message.Serializer, Message.EmittedEvent.TrackExceptionEvent( this.player.guildId.toString(), track.toTrack(audioPlayerManager, pluginInfoModifiers), - Exception(exception.message, exception.severity.toLavalink(), getRootCause(exception).toString()) + Exception(exception.message, exception.severity.toLavalink(), rootCause.toString(), rootCause.stackTraceToString()) ) ) } diff --git a/LavalinkServer/src/main/java/lavalink/server/util/util.kt b/LavalinkServer/src/main/java/lavalink/server/util/util.kt index 55bbd46d3..7573a032e 100644 --- a/LavalinkServer/src/main/java/lavalink/server/util/util.kt +++ b/LavalinkServer/src/main/java/lavalink/server/util/util.kt @@ -154,6 +154,7 @@ fun FriendlyException.Severity.toLavalink() = when (this) { fun Exception.Companion.fromFriendlyException(e: FriendlyException) = Exception( e.message, Exception.Severity.fromFriendlyException(e.severity), + e.toString(), e.stackTraceToString() ) diff --git a/docs/api/rest.md b/docs/api/rest.md index 27daf6930..4ec469e71 100644 --- a/docs/api/rest.md +++ b/docs/api/rest.md @@ -46,10 +46,9 @@ When Lavalink encounters an error, it will respond with a JSON object containing - ## Track API -### Common Types ### {: #track-api-types } +### Common Types ### {: #track-api-types } #### Track @@ -89,16 +88,14 @@ When Lavalink encounters an error, it will respond with a JSON object containing This endpoint is used to resolve audio tracks for use with the [Update Player](#update-player) endpoint. - !!! tip - + Lavalink supports searching via YouTube, YouTube Music, and Soundcloud. To search, you must prefix your identifier with `ytsearch:`, `ytmsearch:` or `scsearch:` respectively. When a search prefix is used, the returned `loadType` will be `search`. Note that disabling the respective source managers renders these search prefixes useless. Plugins may also implement prefixes to allow for more search engines to be utilised. - ``` GET /v4/loadtracks?identifier=dQw4w9WgXcQ ``` @@ -203,7 +200,7 @@ Empty object. ```yaml { "loadType": "empty", - "data": {} + "data": { } } ``` @@ -219,10 +216,11 @@ Empty object. ```yaml { "loadType": "error", - "data": { + "data": { "message": "Something went wrong", "severity": "fault", - "cause": "..." + "cause": "...", + "causeStackTrace": "...", } } ``` @@ -330,7 +328,7 @@ Array of [Track](#track) objects ## Player API -### Common Types ### {: #player-api-types } +### Common Types ### {: #player-api-types } #### Player @@ -356,7 +354,6 @@ Array of [Track](#track) objects `sessionId` is provided by the Voice State Update event sent by Discord, whereas the `endpoint` and `token` are provided with the Voice Server Update. Please refer to https://discord.com/developers/docs/topics/gateway-events#voice - #### Filters Filters are used in above requests and look like this @@ -731,7 +728,7 @@ When `identifier` is used, Lavalink will try to resolve the identifier as a sing { "track": { "encoded": "...", - "identifier": "...", + "identifier": "...", "userData": { ... } }, "endTime": 0, @@ -781,7 +778,7 @@ Response: "time": 1500467109, "position": 60000, "connected": true, - "ping": 50 + "ping": 50 }, "voice": { "token": "...", @@ -1018,7 +1015,6 @@ Response: Additionally, there are a few REST endpoints for the ip rotation extension. - ### Common Types ### {: #route-planner-api-types } #### Route Planner Types diff --git a/docs/api/websocket.md b/docs/api/websocket.md index fe3f18516..7ceef916f 100644 --- a/docs/api/websocket.md +++ b/docs/api/websocket.md @@ -331,11 +331,12 @@ Dispatched when a track throws an exception. ##### Exception Object -| Field | Type | Description | -|----------|-----------------------|-------------------------------| -| message | ?string | The message of the exception | -| severity | [Severity](#severity) | The severity of the exception | -| cause | string | The cause of the exception | +| Field | Type | Description | +|-----------------|-----------------------|-----------------------------------| +| message | ?string | The message of the exception | +| severity | [Severity](#severity) | The severity of the exception | +| cause | string | The cause of the exception | +| causeStackTrace | string | The full stack trace of the cause | ##### Severity @@ -373,7 +374,8 @@ Dispatched when a track throws an exception. "exception": { "message": "...", "severity": "common", - "cause": "..." + "cause": "...", + "causeStackTrace": "..." } } ``` diff --git a/protocol/src/commonMain/kotlin/dev/arbjerg/lavalink/protocol/v4/loadResult.kt b/protocol/src/commonMain/kotlin/dev/arbjerg/lavalink/protocol/v4/loadResult.kt index db289f9c3..713b7afaf 100644 --- a/protocol/src/commonMain/kotlin/dev/arbjerg/lavalink/protocol/v4/loadResult.kt +++ b/protocol/src/commonMain/kotlin/dev/arbjerg/lavalink/protocol/v4/loadResult.kt @@ -151,7 +151,8 @@ data class Playlist( data class Exception( val message: String?, val severity: Severity, - val cause: String + val cause: String, + val causeStackTrace: String ) : LoadResult.Data { /** diff --git a/protocol/src/commonTest/kotlin/LoadResultSerializerTest.kt b/protocol/src/commonTest/kotlin/LoadResultSerializerTest.kt index af921b860..805507b25 100644 --- a/protocol/src/commonTest/kotlin/LoadResultSerializerTest.kt +++ b/protocol/src/commonTest/kotlin/LoadResultSerializerTest.kt @@ -70,7 +70,8 @@ class LoadResultSerializerTest { "data": { "message": "The uploader has not made this video available in your country.", "severity": "common", - "cause": "com.sedmelluq.discord.lavaplayer.tools.FriendlyException: This video is not available in your country." + "cause": "com.sedmelluq.discord.lavaplayer.tools.FriendlyException: This video is not available in your country.", + "causeStackTrace": "com.sedmelluq.discord.lavaplayer.tools.FriendlyException: This video is not available in your country.\n\nblabla" } } """.trimIndent() @@ -83,6 +84,7 @@ class LoadResultSerializerTest { message shouldBe "The uploader has not made this video available in your country." severity shouldBe Exception.Severity.COMMON cause shouldBe "com.sedmelluq.discord.lavaplayer.tools.FriendlyException: This video is not available in your country." + causeStackTrace shouldBe "com.sedmelluq.discord.lavaplayer.tools.FriendlyException: This video is not available in your country.\n\nblabla" } } }