dom_exception.go raw

   1  //go:build js && wasm
   2  // +build js,wasm
   3  
   4  package idb
   5  
   6  import (
   7  	"syscall/js"
   8  
   9  	"github.com/hack-pad/safejs"
  10  )
  11  
  12  func tryAsDOMException(err error) error {
  13  	switch err := err.(type) {
  14  	case js.Error:
  15  		return domExceptionAsError(safejs.Safe(err.Value))
  16  	default:
  17  		return err
  18  	}
  19  }
  20  
  21  func domExceptionAsError(jsDOMException safejs.Value) error {
  22  	truthy, err := jsDOMException.Truthy()
  23  	if err != nil || !truthy {
  24  		return err
  25  	}
  26  	domException, err := parseJSDOMException(jsDOMException)
  27  	if err != nil {
  28  		return err
  29  	}
  30  	return domException
  31  }
  32  
  33  // DOMException is a JavaScript DOMException with a standard name.
  34  // Use errors.Is() to compare by name.
  35  type DOMException struct {
  36  	name    string
  37  	message string
  38  }
  39  
  40  // NewDOMException returns a new DOMException with the given name.
  41  // Only useful for errors.Is() comparisons with errors returned from idb.
  42  func NewDOMException(name string) DOMException {
  43  	return DOMException{name: name}
  44  }
  45  
  46  func parseJSDOMException(jsDOMException safejs.Value) (DOMException, error) {
  47  	name, err := jsDOMException.Get("name")
  48  	if err != nil {
  49  		return DOMException{}, err
  50  	}
  51  	nameStr, err := name.String()
  52  	if err != nil {
  53  		return DOMException{}, err
  54  	}
  55  	message, err := jsDOMException.Get("message")
  56  	if err != nil {
  57  		return DOMException{}, err
  58  	}
  59  	messageStr, err := message.String()
  60  	if err != nil {
  61  		return DOMException{}, err
  62  	}
  63  	return DOMException{
  64  		name:    nameStr,
  65  		message: messageStr,
  66  	}, nil
  67  }
  68  
  69  func (e DOMException) Error() string {
  70  	if e.message == "" {
  71  		return e.name
  72  	}
  73  	return e.name + ": " + e.message
  74  }
  75  
  76  // Is returns true target is a DOMException and matches this DOMException's name. Use 'errors.Is()' to call it.
  77  func (e DOMException) Is(target error) bool {
  78  	targetDOMException, ok := target.(DOMException)
  79  	return ok && targetDOMException.name == e.name
  80  }
  81