mergify[bot] on master
Update chameleon to 0.3.5 (#155) (compare)
mergify[bot] on master
Update sbt-tpolecat to 0.3.1 (#… (compare)
mergify[bot] on master
Update sbt-scalajs, scalajs-com… (compare)
mergify[bot] on master
Update scalatest to 3.2.12 (#15… (compare)
ClientImpl#execute
taking R
log
(stringify) it, so there is only toString or pattern matching. Not sure what could be a better approach.
Future
or Task
or your result type. So in order to not do the logging on each method call, you can define the loghandler through which all requests with their results go.
List
with two strings (the trait name and the method name). See: https://github.com/cornerman/sloth/blob/master/sloth/src/main/scala/Router.scala#L13
LogHandler
and in production the LogHandler
is empty. Otherwise, I agree with you - you normally want to log failures.
chameleon
hinders a merge of the PR: cornerman/sloth#55
I have been strugling to find a way to receive failed Futures (with exceptions) with RPC and Akka-Http / Sloth / Boopickle and therefore made a minimal project to test with the following commands:
git clone https://github.com/marcgrue/scalajs-rpc-exception-test.git
cd scalajs-rpc-exception-test
sbt rpcJVM/run
And in another process
sbt test
Maybe the problem is not related to Sloth but rather Boopickle or my Akka-Http setup. I would be most gratefull if someone could give me a hint... Thanks in advance!
I found the problem! Project is update and everything works now. The reason, only a single Byte was de-serialized was that I took a serialized failed future (with an exception) and tried to de-serialize it to the return type of the API method which in this case was an Int. The response data from the Ajax call needs to be de-serialized with either the API method result type T
OR Throwable
for serialized failed futures!
To determine whether serialized data is of a successful or failed future, one could try to unpickle it with Throwable to see if boopickle recognized it as so, and then otherwise unpickle with the API method return type. But that would require to duplicate the ByteBuffer to avoid a BufferUnderflowException (consume it twice) which is of course a bad idea. I tried to send a response head with a exception-or-not flag but didn't get that to work. So I went for a bit of a hack by adding a byte of 0 or 1 to the beginning of the ByteBuffer so the client can know which type of de-serializing should be done.
My problem didn't show up in the Sloth tests since they don't use Ajax which requires both successful and failed futures to be serialized with the same PickleType (in this case ByteBuffer) but de-serialized with T or Throwable. @cornerman - it might be worth to mention in your readme (unless I have missed to do it the right way :-)
Hi @marcgrue, sorry for answering so late to your question. First of all, thank you for setting up this example!
You are right, sloth does not directly support you when you want transport a failure in your F[_]
type of the router and client. So somehow signaling the error in the protocol in your router and client is correct. Though, in this case, you could also make use of the HTTP status code. Like a 200
means success and you can just return it. And a status code like 404
or 400
or 500
could mean that you have a pickled exception.
Another approach is to move the error from the F[_]
type into the method in question. Like:
trait Api[F[_]] {
def something: F[Either[Throwable, Int]]
}
Thereby, the router will actually serialize the throwable just as expected. And the client can use it. But that of course means, that you need to handle it on the client side explicitly.