Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
412c2f48ea
|
@@ -3,6 +3,7 @@ examples/connect-desktop/build
|
||||
examples/connect-desktop/frontend/dist
|
||||
examples/connect-desktop/frontend/wailsjs
|
||||
examples/connect/connect
|
||||
examples/errors/errors
|
||||
examples/pairchat/pairchat
|
||||
examples/timeserve/timeserve
|
||||
iroh-go/target/
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package iroh_ffi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// As casts an error to IrohError and back, extracting relevant error message
|
||||
// information. It is a single argument variant of the typical errors.As API
|
||||
// because we always expect an IrohError back from the iroh FFI bindings. The
|
||||
// bindings do not return an IrohError for reasons and will not for the
|
||||
// forseeable future due to API stability guarantees.
|
||||
func As(err error) error {
|
||||
if err, ok := errors.AsType[IrohError](err); ok {
|
||||
return errors.New(fmt.Sprintf("%s: %s", err.Message(), err.DebugMessage()))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Is suports matching against the stable iroh error taxonomy using the error
|
||||
// sentinel construction below. The caller must pass in a valid error sentinel
|
||||
// specified by this library, e.g. iroh.BindError.
|
||||
func (e *IrohError) Is(target error) bool {
|
||||
if err, ok := errors.AsType[sentinel](target); ok {
|
||||
return uint(e.Kind()) == err.kind
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type sentinel struct {
|
||||
kind uint
|
||||
message string
|
||||
}
|
||||
|
||||
func (s sentinel) Error() string {
|
||||
return s.message
|
||||
}
|
||||
|
||||
var InvalidInputError error = sentinel{
|
||||
kind: uint(IrohErrorKindInvalidInput),
|
||||
message: "iroh: invalid input supplied by the caller",
|
||||
}
|
||||
|
||||
var BindError error = sentinel{
|
||||
kind: uint(IrohErrorKindBind),
|
||||
message: "iroh: failure while initiating or completing an outgoing connection",
|
||||
}
|
||||
|
||||
var ConnectError error = sentinel{
|
||||
kind: uint(IrohErrorKindConnect),
|
||||
message: "iroh: failure while initiating or completing an outgoing connectio",
|
||||
}
|
||||
|
||||
var ConnectionError error = sentinel{
|
||||
kind: uint(IrohErrorKindConnection),
|
||||
message: "iroh: an established connection failed or closed unexpectedly",
|
||||
}
|
||||
|
||||
var AlpnError error = sentinel{
|
||||
kind: uint(IrohErrorKindAlpn),
|
||||
message: "iroh: ALPN negotiation or lookup failed",
|
||||
}
|
||||
|
||||
var KeyParsingError error = sentinel{
|
||||
kind: uint(IrohErrorKindKeyParsing),
|
||||
message: "iroh: endpoint id / public key parsing failed",
|
||||
}
|
||||
|
||||
var TicketParsingError error = sentinel{
|
||||
kind: uint(IrohErrorKindKeyParsing),
|
||||
message: "iroh: ticket parsing failed",
|
||||
}
|
||||
|
||||
var RelayError error = sentinel{
|
||||
kind: uint(IrohErrorKindRelay),
|
||||
message: "iroh: stream read/write/control operation failed",
|
||||
}
|
||||
|
||||
var StreamError error = sentinel{
|
||||
kind: uint(IrohErrorKindStream),
|
||||
message: "iroh: datagram send/receive operation failed",
|
||||
}
|
||||
|
||||
var DatagramError error = sentinel{
|
||||
kind: uint(IrohErrorKindDatagram),
|
||||
message: "iroh: datagram send/receive operation failed",
|
||||
}
|
||||
|
||||
var FCallbackError error = sentinel{
|
||||
kind: uint(IrohErrorKindCallback),
|
||||
message: "iroh: foreign callback failed",
|
||||
}
|
||||
|
||||
var ClosedError error = sentinel{
|
||||
kind: uint(IrohErrorKindClosed),
|
||||
message: "iroh: operation was attempted on a closed stream/connection/resource",
|
||||
}
|
||||
|
||||
var TimeoutError error = sentinel{
|
||||
kind: uint(IrohErrorKindTimeout),
|
||||
message: "iroh: operation timed out",
|
||||
}
|
||||
|
||||
var InternalError error = sentinel{
|
||||
kind: uint(IrohErrorKindInternal),
|
||||
message: "iroh: unclassified internal error",
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# errors
|
||||
|
||||
How to deal with error handling in a convenient way. See
|
||||
[`#263`](https://github.com/n0-computer/iroh-ffi/issues/263) for the juicy
|
||||
details.
|
||||
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
iroh "git.coopcloud.tech/decentral1se/iroh-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
preset := iroh.PresetN0DisableRelay()
|
||||
opts := iroh.EndpointOptions{
|
||||
Preset: &preset,
|
||||
Alpns: &[][]byte{[]byte("iroh-go-errors/0")},
|
||||
}
|
||||
|
||||
endpoint, err := iroh.EndpointBind(opts)
|
||||
|
||||
// BEGIN API PREVIEW ZONE
|
||||
|
||||
// 1. convert error to IrohError with As
|
||||
// bring IrohError.Message/DebugMessage back
|
||||
// maintain `err != nil` compatibility
|
||||
if err := iroh.As(err); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 1. no As machinery required
|
||||
// sentinel check with errors.Is support
|
||||
// works like usual `err`
|
||||
if err != nil && errors.Is(err, iroh.BindError) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// END API PREVIEW ZONE
|
||||
|
||||
endpoint.Online()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module git.coopcloud.tech/decentral1se/iroh-go/examples/errors
|
||||
|
||||
go 1.26.1
|
||||
|
||||
require git.coopcloud.tech/decentral1se/iroh-go v0.0.0-20260717110820-68ad06fe2a25
|
||||
|
||||
replace git.coopcloud.tech/decentral1se/iroh-go => ../../
|
||||
Reference in New Issue
Block a user