]> Cypherpunks repositories - gostls13.git/commitdiff
syscall/js: improve panic messages
authorRichard Musiol <mail@richard-musiol.de>
Thu, 5 Jul 2018 17:55:08 +0000 (19:55 +0200)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 9 Jul 2018 23:04:30 +0000 (23:04 +0000)
This commit adds the actual type to the panic message when calling
a method of Value on a Value with a bad type. It also adds better
panic messages to Value.Invoke and Value.Call.

Change-Id: Ic4b3aa29d3bef8e357be40cd07664ad602ffab12
Reviewed-on: https://go-review.googlesource.com/122376
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/syscall/js/js.go
src/syscall/js/js_test.go

index cc7907a9281f723f89baf41d635a6fd7a22705e6..0cc98bd52c631bd6803c1b798c24eba200d6adb0 100644 (file)
@@ -257,6 +257,12 @@ func valueLength(v ref) int
 func (v Value) Call(m string, args ...interface{}) Value {
        res, ok := valueCall(v.ref, m, makeArgs(args))
        if !ok {
+               if vType := v.Type(); vType != TypeObject && vType != TypeFunction { // check here to avoid overhead in success case
+                       panic(&ValueError{"Value.Call", vType})
+               }
+               if propType := v.Get(m).Type(); propType != TypeFunction {
+                       panic("syscall/js: Value.Call: property " + m + " is not a function, got " + propType.String())
+               }
                panic(Error{makeValue(res)})
        }
        return makeValue(res)
@@ -269,6 +275,9 @@ func valueCall(v ref, m string, args []ref) (ref, bool)
 func (v Value) Invoke(args ...interface{}) Value {
        res, ok := valueInvoke(v.ref, makeArgs(args))
        if !ok {
+               if vType := v.Type(); vType != TypeFunction { // check here to avoid overhead in success case
+                       panic(&ValueError{"Value.Invoke", vType})
+               }
                panic(Error{makeValue(res)})
        }
        return makeValue(res)
@@ -292,17 +301,21 @@ func (v Value) isNumber() bool {
        return v.ref>>32&nanHead != nanHead || v.ref == valueNaN.ref
 }
 
-// Float returns the value v as a float64. It panics if v is not a JavaScript number.
-func (v Value) Float() float64 {
+func (v Value) float(method string) float64 {
        if !v.isNumber() {
-               panic("syscall/js: not a number")
+               panic(&ValueError{method, v.Type()})
        }
        return *(*float64)(unsafe.Pointer(&v.ref))
 }
 
+// Float returns the value v as a float64. It panics if v is not a JavaScript number.
+func (v Value) Float() float64 {
+       return v.float("Value.Float")
+}
+
 // Int returns the value v truncated to an int. It panics if v is not a JavaScript number.
 func (v Value) Int() int {
-       return int(v.Float())
+       return int(v.float("Value.Int"))
 }
 
 // Bool returns the value v as a bool. It panics if v is not a JavaScript boolean.
@@ -313,7 +326,7 @@ func (v Value) Bool() bool {
        case valueFalse.ref:
                return false
        default:
-               panic("syscall/js: not a boolean")
+               panic(&ValueError{"Value.Bool", v.Type()})
        }
 }
 
@@ -335,3 +348,15 @@ func (v Value) InstanceOf(t Value) bool {
 }
 
 func valueInstanceOf(v ref, t ref) bool
+
+// A ValueError occurs when a Value method is invoked on
+// a Value that does not support it. Such cases are documented
+// in the description of each method.
+type ValueError struct {
+       Method string
+       Type   Type
+}
+
+func (e *ValueError) Error() string {
+       return "syscall/js: call of " + e.Method + " on " + e.Type.String()
+}
index d47afe1da7e8ee8d79377da9c2c8fee31449c150..753e262d52e83f45c2073a124c1bf4a885c968c2 100644 (file)
@@ -53,6 +53,12 @@ func TestString(t *testing.T) {
        if dummys.Get("someString") != dummys.Get("someString") {
                t.Errorf("same value not equal")
        }
+
+       wantInt := "42"
+       o = dummys.Get("someInt")
+       if got := o.String(); got != wantInt {
+               t.Errorf("got %#v, want %#v", got, wantInt)
+       }
 }
 
 func TestInt(t *testing.T) {