Commit 2acae874 authored by Richard Musiol's avatar Richard Musiol Committed by Brad Fitzpatrick

syscall/js: improve panic messages

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/122376Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent e97ef412
...@@ -257,6 +257,12 @@ func valueLength(v ref) int ...@@ -257,6 +257,12 @@ func valueLength(v ref) int
func (v Value) Call(m string, args ...interface{}) Value { func (v Value) Call(m string, args ...interface{}) Value {
res, ok := valueCall(v.ref, m, makeArgs(args)) res, ok := valueCall(v.ref, m, makeArgs(args))
if !ok { 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)}) panic(Error{makeValue(res)})
} }
return makeValue(res) return makeValue(res)
...@@ -269,6 +275,9 @@ func valueCall(v ref, m string, args []ref) (ref, bool) ...@@ -269,6 +275,9 @@ func valueCall(v ref, m string, args []ref) (ref, bool)
func (v Value) Invoke(args ...interface{}) Value { func (v Value) Invoke(args ...interface{}) Value {
res, ok := valueInvoke(v.ref, makeArgs(args)) res, ok := valueInvoke(v.ref, makeArgs(args))
if !ok { 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)}) panic(Error{makeValue(res)})
} }
return makeValue(res) return makeValue(res)
...@@ -292,17 +301,21 @@ func (v Value) isNumber() bool { ...@@ -292,17 +301,21 @@ func (v Value) isNumber() bool {
return v.ref>>32&nanHead != nanHead || v.ref == valueNaN.ref 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(method string) float64 {
func (v Value) Float() float64 {
if !v.isNumber() { if !v.isNumber() {
panic("syscall/js: not a number") panic(&ValueError{method, v.Type()})
} }
return *(*float64)(unsafe.Pointer(&v.ref)) 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. // Int returns the value v truncated to an int. It panics if v is not a JavaScript number.
func (v Value) Int() int { 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. // 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 { ...@@ -313,7 +326,7 @@ func (v Value) Bool() bool {
case valueFalse.ref: case valueFalse.ref:
return false return false
default: default:
panic("syscall/js: not a boolean") panic(&ValueError{"Value.Bool", v.Type()})
} }
} }
...@@ -335,3 +348,15 @@ func (v Value) InstanceOf(t Value) bool { ...@@ -335,3 +348,15 @@ func (v Value) InstanceOf(t Value) bool {
} }
func valueInstanceOf(v ref, t ref) 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()
}
...@@ -53,6 +53,12 @@ func TestString(t *testing.T) { ...@@ -53,6 +53,12 @@ func TestString(t *testing.T) {
if dummys.Get("someString") != dummys.Get("someString") { if dummys.Get("someString") != dummys.Get("someString") {
t.Errorf("same value not equal") 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) { func TestInt(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment