fix(claw): read a blank since as unset instead of failing the request
The phone's notification poll sent `since` unconditionally, and before the first ack there is no cursor at all, so it went out as `?since=`. Axum's `Query` hands a present-but-empty parameter through as an empty string, and `Option<i64>` only forgives a *missing* key, so the whole poll answered `400 Failed to deserialize query string: since: cannot parse integer from empty string` and the phone showed an error instead of an empty queue. Both ends: the client omits `since` unless it has a positive id to send, and a `blank_as_none` deserializer makes a blank value mean "not set" for `NotificationQuery` and `EventStreamQuery` alike — an empty `since` reads as "from the start" however it got there.
This commit is contained in:
1 parent
3283d92227
commit
9e132fdf71
2 files changed
+48
-4
No files matched your search
@@ -138,12 +138,21 @@ class ClawApi(
|
||||
return execute(builder.delete().build()) { }
|
||||
}
|
||||
|
||||
// GET /v1/notifications?device=&since=N. `since` is the last id the
|
||||
// device has acked; before the first ack there is no cursor at all,
|
||||
// and an empty `since=` came back
|
||||
// "HTTP 400 — Failed to deserialize query string: since: cannot
|
||||
// parse integer from empty string", which failed the whole poll.
|
||||
// So the parameter is sent only when there is a positive id to send:
|
||||
// absent and blank mean the same thing to the claw, and the shorter
|
||||
// request is the honest one.
|
||||
suspend fun notifications(deviceId: String, since: String): ClawResult<List<RhemaNotification>> {
|
||||
val base = baseOrNull() ?: return ClawResult.Network("no base URL configured")
|
||||
val cursor = since.trim().toLongOrNull()?.takeIf { it > 0 }
|
||||
val url = base.toHttpUrlOrNull()?.newBuilder()
|
||||
?.addPathSegments("v1/notifications")
|
||||
?.addQueryParameter("device", deviceId)
|
||||
?.addQueryParameter("since", since)
|
||||
?.apply { cursor?.let { addQueryParameter("since", it.toString()) } }
|
||||
?.build()
|
||||
?: return ClawResult.Network("bad base URL")
|
||||
val request = Request.Builder().url(url).header("Authorization", bearer()).build()
|
||||
|
||||
Reference in new issue
Block a user