# Capnp: Uri format and possible error cases for capabilities

**URL:** https://discuss.ocaml.org/t/capnp-uri-format-and-possible-error-cases-for-capabilities/5378
**Category:** Learning
**Tags:** capnp
**Created:** [March 25, 2020, 6:50pm UTC](https://discuss.ocaml.org/t/capnp-uri-format-and-possible-error-cases-for-capabilities/5378 "2020-03-25T18:50:03Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Cjen1](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cjen1/32/1731_2.png) [@Cjen1](https://discuss.ocaml.org/u/Cjen1)
#### Post date: [March 25, 2020, 6:50pm UTC](https://discuss.ocaml.org/t/capnp-uri-format-and-possible-error-cases-for-capabilities/5378/1 "2020-03-25T18:50:03Z")

</div>

I’m trying to implement a consensus system and want to use capnp internally (I’m not going to end up using the pipe-lining features, but was looking for a well engineered, minimally buggy library).

There are two things that I can’t quite work out.

- How to get a capability(service) for a remote server, (as in how are the uri’s specified).
- What errors can be thrown when doing an rpc, thus allowing me to automatically retry if the network dies/server dies.

Uri: So I just noticed that there was a line later on in the example for a python client connecting

```auto
capnp://insecure@127.0.0.1:7000

```

However I’d imagine that the `insecure` part of the uri should be replaced by the id of the service?

Automatically retrying: The main issue with this is that I can’t see what errors could be thrown by the rpc, thus which are recoverable.  
Specifically I need this to be resistant to node failures, so if a capability errors out, then I presume that I need to re-fetch that capability from the uri/sturdy-ref.  
I’d expect the errors to be thrown in cases where the network had failed, however would those just be the errors of the underlying socket?

It has been quite cool to work with so far and I would love to use this in my project!

---

<div class="post-metadata">

### Author: ![talex5](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/talex5/32/353_2.png) [@talex5](https://discuss.ocaml.org/u/talex5)
#### Post date: [March 26, 2020, 9:46am UTC](https://discuss.ocaml.org/t/capnp-uri-format-and-possible-error-cases-for-capabilities/5378/2 "2020-03-26T09:46:15Z")

</div>

The server can use [`Capnp_rpc_unix.Cap_file.save_service`](https://mirage.github.io/capnp-rpc/capnp-rpc-unix/Capnp_rpc_unix/Cap_file/index.html#val-save_service) to write out a `.cap` file with the address, which you can then give to the client. There is no way for the client to guess the URI itself, because the URI includes a secret granting the client access to the service.

See the example in [https://github.com/mirage/capnp-rpc#networking](https://github.com/mirage/capnp-rpc#networking), which also describes the components of the URI.

You can use [`Capability.problem`](https://mirage.github.io/capnp-rpc/capnp-rpc-lwt/Capnp_rpc_lwt/Capability/index.html#val-problem) when you get an exception to check if your connection to the service is still OK. [`Capnp_rpc.Exception`](https://mirage.github.io/capnp-rpc/capnp-rpc/Capnp_rpc/Exception/index.html) has a type field which includes `Disconnected` as one of the options.

You could also use `Capability.when_broken` to register a callback that will be called as soon as the connection to the service fails, in case you want to reconnect immediately, rather than waiting until the next call fails.

In summary:

1. Some `service.foo()` call fails, returning an exception.
2. You can use `Capability.problem service` to see whether your connection to the service itself is still OK (this just checks some local state and is very fast).
3. If there’s no problem with `service`, you are free to make more calls on the object (the exception you got was just for that call). Otherwise, either use your sturdy-ref to get a new connection or (if you don’t have one) propagate the exception until it reaches someone who does and can restart from there.

---

<div class="post-metadata">

### Author: ![Cjen1](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cjen1/32/1731_2.png) [@Cjen1](https://discuss.ocaml.org/u/Cjen1)
#### Post date: [March 26, 2020, 12:23pm UTC](https://discuss.ocaml.org/t/capnp-uri-format-and-possible-error-cases-for-capabilities/5378/3 "2020-03-26T12:23:22Z")

</div>

I take it then that the .cap file then needs to be passed out of band to the clients? Or alternatively use the `insecure` keyword instead, but then I’m presuming that the service id would be unguessable?

---

<div class="post-metadata">

### Author: ![talex5](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/talex5/32/353_2.png) [@talex5](https://discuss.ocaml.org/u/talex5)
#### Post date: [March 26, 2020, 1:24pm UTC](https://discuss.ocaml.org/t/capnp-uri-format-and-possible-error-cases-for-capabilities/5378/4 "2020-03-26T13:24:17Z")

</div>

> I take it then that the .cap file then needs to be passed out of band to the clients?

Yes. If you already had a capnp connection, you could use [the persistence API](https://github.com/mirage/capnp-rpc#implementing-the-persistence-api) instead.

> Or alternatively use the `insecure` keyword instead, but then I’m presuming that the service id would be unguessable?

`insecure` is only for interop with endpoints that don’t support TLS at all. It won’t work with a normal (TLS-enabled) endpoint.
