mergify[bot] on master
Update scalafmt-core to 3.5.3 Merge pull request #1440 from s… (compare)
mergify[bot] on master
Update zio-interop-reactivestre… Merge pull request #1439 from s… (compare)
Hi guys, I'm seeing a very strange issue when using sttp as a web socket client:
basicRequest.auth
.basic(username, password)
.response(asWebSocketStream(Fs2Streams[F])(webSocketFramePipe(q)))
.get(uri)
.send(backend)
.void
Sometimes I'm seeing this exception when running the above code:
sttp.client3.DeserializationException: exhausted input
I'm suspecting this is an upstream server issue (it gets resolved when they restart it). On the other side using python I can connect without those issues. Anybody has seen something similar or has a hint on how to trace it down?
Defect in zio.Has: Set(SttpBackend[=λ %2:0 → ZIO[-Any,+Throwable,+2:0],+{ZioStreams & package::WebSockets}])
mentioned above. I'm just not sure why, because I think I'm using the right versions (sttp = 3.0.0, zio = 1.0.3, tapir = 0.17.7). Any ideas?
v2
missing.
String
urls until this is fixed?
Not in gzip format
. This is presumably because STTP is attempting to decompress what has already been decompressed by the http4s middleware. This suggests that backends shouldn't do their own decompression, is that true?
send
method from sttp.client3.asynchttpclient.zio._
package to make the request. But when I am trying to write unit test cases for that, I found https://sttp.softwaremill.com/en/latest/testing.html send(backEnd)
method with passing backend. I check, there is stubbing
in sttp.client3.asynchttpclient
package, but not sure, is it used for unit test our not? Another question, Do we have predefined ZIO backend
or we need to define our own? for passing into the send(...)
method.
Hi all. I couldn't find in sttp documentation if it is possible to describe a google batch request with sttp.
https://developers.google.com/gmail/api/guides/batch#batch-example-request
POST /batch/farm/v1 HTTP/1.1
Authorization: Bearer your_auth_token
Host: www.googleapis.com
Content-Type: multipart/mixed; boundary=batch_foobarbaz
Content-Length: total_content_length
--batch_foobarbaz
Content-Type: application/http
Content-ID: <item1:12930812@barnyard.example.com>
GET /farm/v1/animals/pony
--batch_foobarbaz
Content-Type: application/http
Content-ID: <item2:12930812@barnyard.example.com>
PUT /farm/v1/animals/sheep
Content-Type: application/json
Content-Length: part_content_length
If-Match: "etag/sheep"
{
"animalName": "sheep",
"animalAge": "5"
"peltColor": "green",
}
--batch_foobarbaz
Content-Type: application/http
Content-ID: <item3:12930812@barnyard.example.com>
GET /farm/v1/animals
If-None-Match: "etag/animals"
--batch_foobarbaz--
Is there a way to call google batch api with sttp client?
multipartBody
, but I couldn't find a way how to set an url for each part
ok I did a bit of investigation and here's where I am at the moment:
No WebSocketUpgradeHandler but scheme is ws
java.lang.IllegalArgumentException: No WebSocketUpgradeHandler but scheme is ws
at org.asynchttpclient.netty.request.NettyRequestSender.validateWebSocketRequest(NettyRequestSender.java:571)
at org.asynchttpclient.netty.request.NettyRequestSender.sendRequest(NettyRequestSender.java:95)
at org.asynchttpclient.DefaultAsyncHttpClient.execute(DefaultAsyncHttpClient.java:259)
at org.asynchttpclient.DefaultAsyncHttpClient.executeRequest(DefaultAsyncHttpClient.java:228)
at org.asynchttpclient.BoundRequestBuilder.execute(BoundRequestBuilder.java:35)
at sttp.client3.asynchttpclient.AsyncHttpClientBackend.$anonfun$sendRegular$1(AsyncHttpClientBackend.scala:59)
at sttp.client3.impl.monix.TaskMonadAsyncError$.$anonfun$async$1(TaskMonadAsyncError.scala:18)
at cancelable @ sttp.client3.impl.monix.TaskMonadAsyncError$.async(TaskMonadAsyncError.scala:17)
I get that ^^ my code is:
uri.flatMap[Vector[String]] { uri =>
AsyncHttpClientMonixBackend()
.flatMap { backend =>
basicRequest
.get(Uri(uri))
.body(msg)
.send(backend)
.flatMapLoop(Vector.empty[String]) { (each, acc: Vector[String], continue) =>
Task
.fromEither[String, String] { e: String => new Exception(e) }(each.body)
.flatMap { response =>
val newList = acc :+ response
if (terminateOn(newList))
continue(newList)
else Task.pure(newList)
}
}
.guarantee(backend.close())
}
}
uri.flatMap[Response[Either[String, Vector[String]]]] { uri =>
AsyncHttpClientMonixBackend()
.flatMap { backend =>
basicRequest
.get(Uri(uri))
.body(msg)
.response(
asWebSocket((f: WebSocket[Task]) =>
f.sendText(msg) *> f.receiveText().flatMapLoop(Vector.empty[String]) { (each, acc, continue) =>
val nAcc = acc :+ each
println(nAcc)
if (terminateOn(nAcc)) {
Task.pure(nAcc)
} else continue(nAcc)
}
)
)
.send(backend)
}
}
def uploadFile[T](
url: String,
file: File,
headers: Map[String, String],
responseMapper: String => T
): Task[T] =
for {
request <- Task.effect(
basicRequest
.body(file)
.readTimeout(2.minutes)
.put(uri"$url")
.headers(headers)
)
result <- send(request)
.provideLayer(sttpBackendLayer)
.flatMap { response =>
if (response.isSuccess)
response.body.fold(
error => Task.fail(new RuntimeException(error)),
stringRes => Task.effect(responseMapper(stringRes))
)
else Task.fail(new RuntimeException(response.statusText))
}
} yield result
Hi guys! I have a service with WebSocket stream created as
basicRequest
.get(uri)
.response(asWebSocketStream(Fs2Streams[F])(pipe))
.send(backend)
where backend is SttpBackend[F, Fs2Streams[F] with capabilities.WebSockets]
Any chance to create a stub for testing stream?
Thanks in advance
I am having a huge pain with documentation.
You often have:
import sttp.client3.httpclient.zio.HttpClientZioBackend
HttpClientZioBackend().flatMap { backend => ??? }
However I have no idea what I should put instead of ??? in the flatmap.
Also, I do not understand how can I retrieve the zio runtime for the sttp client so I can just do runtime.unsafeRun(myRequest)
I was wondering what was the best way to handle error with STTP and the ZIO backend.
The send
method returns Throwable
with (as explained in the doc) known error converted to SttpClientException
.
Addind to that the circe decoding exception in a ResponseException
, this become really tedious to deal with.
Do you have any recommendation ?
Let's assume the following piece of code:
override def send[T](
request: Request[MatrixResponse[T], Any]
): ZIO[Any, ResponseException[ResponseError, io.circe.Error], T] = {
for {
result <- sendRequest(request).provide(client) // Throwable (low level error, network error, ...)
json <- ZIO.fromEither(result.body) // ResponseException (API error OR circe error)
} yield json
}
It does not compile because (sendRequest
an alias to STTP send
) sendRequest
can fail with Throwable.
I would like to avoid forwarding this Throwable
up to the caller, because it's confusing and does not make the type signature very useful.
Another solution would be to "flatten" those error (network error, api error and serialization errors) by creating an ADT to wrap them, is it a good solution ?
I'm writing a VCR lib with sttp which means I have to wrap any HTTP backend in a general way and have it still work. One thing I'm struggling with is converting an arbitrary response T
to a String. I have this dirty hack currently that I want to get rid of:
https://github.com/reibitto/be-kind-rewind/blob/a2385dbd96904b39b554770518955f076efcf44c/client-sttp/src/main/scala/bekindrewind/sttpclient/VcrBackend.scala#L103-L108
Is there a typeclass I missed or some other mechanism to handle this? Any hints where to look would be appreciated 🙂