github.com/storacha/go-ucanto@v0.7.2/core/result/failure/datamodel/failure.go (about)

     1  package datamodel
     2  
     3  import (
     4  	// to use go:embed
     5  	_ "embed"
     6  	"fmt"
     7  
     8  	"github.com/ipld/go-ipld-prime"
     9  	"github.com/ipld/go-ipld-prime/schema"
    10  	ucanipld "github.com/storacha/go-ucanto/core/ipld"
    11  )
    12  
    13  //go:embed failure.ipldsch
    14  var failureSchema []byte
    15  
    16  // FailureModel is a generic failure
    17  type FailureModel struct {
    18  	Name    *string
    19  	Message string
    20  	Stack   *string
    21  }
    22  
    23  func (f FailureModel) Error() string {
    24  	return f.Message
    25  }
    26  
    27  func (f *FailureModel) ToIPLD() (ipld.Node, error) {
    28  	return ucanipld.WrapWithRecovery(f, typ)
    29  }
    30  
    31  var typ schema.Type
    32  
    33  func init() {
    34  	ts, err := ipld.LoadSchemaBytes(failureSchema)
    35  	if err != nil {
    36  		panic(fmt.Errorf("loading failure schema: %w", err))
    37  	}
    38  	typ = ts.TypeByName("Failure")
    39  }
    40  
    41  func FailureType() schema.Type {
    42  	return typ
    43  }
    44  
    45  func Schema() []byte {
    46  	return failureSchema
    47  }
    48  
    49  // Bind binds the IPLD node to a [datamodel.FailureModel]. This works around
    50  // IPLD requiring data to match the schema _exactly_.
    51  //
    52  // Note: the IPLD node is expected to be a map kind, with a "message" key and
    53  // optionally a "name" and "stack" (all values strings). If none of these are
    54  // true then you get back a nil value [datamodel.FailureModel].
    55  func Bind(n ipld.Node) FailureModel {
    56  	f := FailureModel{}
    57  	nn, err := n.LookupByString("name")
    58  	if err == nil {
    59  		name, err := nn.AsString()
    60  		if err == nil {
    61  			f.Name = &name
    62  		}
    63  	}
    64  	mn, err := n.LookupByString("message")
    65  	if err == nil {
    66  		msg, err := mn.AsString()
    67  		if err == nil {
    68  			f.Message = msg
    69  		}
    70  	}
    71  	sn, err := n.LookupByString("stack")
    72  	if err == nil {
    73  		stack, err := sn.AsString()
    74  		if err == nil {
    75  			f.Stack = &stack
    76  		}
    77  	}
    78  	return f
    79  }