errors.go 4.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
package ipld

import (
	"fmt"
)

// ErrWrongKind may be returned from functions on the Node interface when
// a method is invoked which doesn't make sense for the Kind and/or ReprKind
// that node concretely contains.
//
// For example, calling AsString on a map will return ErrWrongKind.
12
// Calling Lookup on an int will similarly return ErrWrongKind.
13
type ErrWrongKind struct {
14 15 16
	// TypeName may optionally indicate the named type of a node the function
	// was called on (if the node was typed!), or, may be the empty string.
	TypeName string
Eric Myhre's avatar
Eric Myhre committed
17

18 19
	// MethodName is literally the string for the operation attempted, e.g.
	// "AsString".
20 21
	//
	// For methods on nodebuilders, we say e.g. "NodeBuilder.CreateMap".
22 23
	MethodName string

24 25 26 27 28
	// ApprorpriateKind describes which ReprKinds the erroring method would
	// make sense for.
	AppropriateKind ReprKindSet

	// ActualKind describes the ReprKind of the node the method was called on.
29 30 31
	//
	// In the case of typed nodes, this will typically refer to the 'natural'
	// data-model kind for such a type (e.g., structs will say 'map' here).
32
	ActualKind ReprKind
33 34 35
}

func (e ErrWrongKind) Error() string {
36 37 38 39 40
	if e.TypeName == "" {
		return fmt.Sprintf("func called on wrong kind: %s called on a %s node, but only makes sense on %s", e.MethodName, e.ActualKind, e.AppropriateKind)
	} else {
		return fmt.Sprintf("func called on wrong kind: %s called on a %s node (kind: %s), but only makes sense on %s", e.MethodName, e.TypeName, e.ActualKind, e.AppropriateKind)
	}
41
}
42

43 44
// ErrNotExists may be returned from the lookup functions of the Node interface
// to indicate a missing value.
45
//
46
// Note that schema.ErrNoSuchField is another type of error which sometimes
47 48 49 50 51
// occurs in similar places as ErrNotExists.  ErrNoSuchField is preferred
// when handling data with constraints provided by a schema that mean that
// a field can *never* exist (as differentiated from a map key which is
// simply absent in some data).
type ErrNotExists struct {
52
	Segment PathSegment
53 54 55 56 57
}

func (e ErrNotExists) Error() string {
	return fmt.Sprintf("key not found: %q", e.Segment)
}
58

Eric Myhre's avatar
Eric Myhre committed
59 60 61 62 63 64
// ErrRepeatedMapKey is an error indicating that a key was inserted
// into a map that already contains that key.
//
// This error may be returned by any methods that add data to a map --
// any of the methods on a NodeAssembler that was yielded by MapAssembler.AssignKey(),
// or from the MapAssembler.AssignDirectly() method.
65 66
type ErrRepeatedMapKey struct {
	Key Node
67 68
}

69 70
func (e ErrRepeatedMapKey) Error() string {
	return fmt.Sprintf("cannot repeat map key (\"%s\")", e.Key)
71 72
}

Eric Myhre's avatar
Eric Myhre committed
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
// ErrInvalidKey indicates a key is invalid for some reason.
//
// This is only possible for typed nodes; specifically, it may show up when
// handling struct types, or maps with interesting key types.
// (Other kinds of key invalidity that happen for untyped maps
// fall under ErrRepeatedMapKey or ErrWrongKind.)
// (Union types use ErrInvalidUnionDiscriminant instead of ErrInvalidKey,
// even when their representation strategy is maplike.)
type ErrInvalidKey struct {
	// TypeName will indicate the named type of a node the function was called on.
	TypeName string

	// Key is the key that was rejected.
	Key Node

	// Reason, if set, may provide details (for example, the reason a key couldn't be converted to a type).
	// If absent, it'll be presumed "no such field".
	Reason error
}

func (e ErrInvalidKey) Error() string {
	if e.Reason == nil {
		return fmt.Sprintf("invalid key for map %s: \"%s\": no such field", e.TypeName, e.Key)
	} else {
		return fmt.Sprintf("invalid key for map %s: \"%s\": %s", e.TypeName, e.Key, e.Reason)
	}
}

101 102 103 104 105 106 107
// ErrIteratorOverread is returned when calling 'Next' on a MapIterator or
// ListIterator when it is already done.
type ErrIteratorOverread struct{}

func (e ErrIteratorOverread) Error() string {
	return "iterator overread"
}
108 109 110 111 112 113

type ErrCannotBeNull struct{} // Review: arguably either ErrInvalidKindForNodeStyle.

type ErrMissingRequiredField struct{}     // only possible for typed nodes -- specifically, struct types.
type ErrListOverrun struct{}              // only possible for typed nodes -- specifically, struct types with list (aka tuple) representations.
type ErrInvalidUnionDiscriminant struct{} // only possible for typed nodes -- specifically, union types.