mirror of https://github.com/sbt/sbt.git
[2.x] fix: Return JSON-RPC error for unknown server methods (#9002)
The fallback ServerHandler silently dropped requests with unknown methods, violating the JSON-RPC spec. Clients like Metals that send unrecognized requests would never receive a response, potentially causing timeouts or hangs. Return a -32601 (Method not found) error response instead. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
00632754ab
commit
d765ba263a
|
|
@ -30,7 +30,10 @@ object ServerHandler {
|
||||||
|
|
||||||
lazy val fallback: ServerHandler = ServerHandler({ handler =>
|
lazy val fallback: ServerHandler = ServerHandler({ handler =>
|
||||||
ServerIntent(
|
ServerIntent(
|
||||||
onRequest = { case x => handler.log.debug(s"Unhandled request received: ${x.method}: $x") },
|
onRequest = { case x =>
|
||||||
|
handler.log.debug(s"Unhandled request received: ${x.method}: $x")
|
||||||
|
handler.jsonRpcRespondError(Some(x.id), -32601, s"Unknown method: ${x.method}")
|
||||||
|
},
|
||||||
onResponse = { case x => handler.log.debug(s"Unhandled response received") },
|
onResponse = { case x => handler.log.debug(s"Unhandled response received") },
|
||||||
onNotification = { case x =>
|
onNotification = { case x =>
|
||||||
handler.log.debug(s"Unhandled notification received: ${x.method}: $x")
|
handler.log.debug(s"Unhandled notification received: ${x.method}: $x")
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,16 @@ class ResponseTest extends AbstractServerTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("unknown method returns error") {
|
||||||
|
val id = svr.session.nextId()
|
||||||
|
svr.session.sendJsonRpc(id, "build/foo", "{}").get
|
||||||
|
val response = svr.session.waitForResponseMsg(10.seconds, id).get
|
||||||
|
assert(
|
||||||
|
response.error.exists(_.code == -32601),
|
||||||
|
s"Expected method-not-found error, got: $response"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private def neverReceiveResponse(
|
private def neverReceiveResponse(
|
||||||
duration: FiniteDuration
|
duration: FiniteDuration
|
||||||
)(predicate: sbt.internal.protocol.JsonRpcResponseMessage => Boolean): Unit =
|
)(predicate: sbt.internal.protocol.JsonRpcResponseMessage => Boolean): Unit =
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue