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