Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Prev Previous commit
Next Next commit
webcrypto: catch JS exception during webcrypto calls
This useful under Safari, when calling an unimplemented feature.
  • Loading branch information
r-l-x committed Apr 20, 2018
commit d0c66ede6abc32e02dd5fd98cf1bb52105ce7f66
23 changes: 17 additions & 6 deletions js/webcrypto/webcrypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func getSubtle() *js.Object {
// }

// SubtleCall calls the object's method with the given arguments assuming that it returns a promise, wait for it to be settled, and returns the result/error.
func SubtleCall(method string, args ...interface{}) (*js.Object, error) {
func SubtleCall(method string, args ...interface{}) (res *js.Object, err error) {
if SubtleCrypto == nil {
return nil, ErrWebCryptoInterfaceNotFound
}
Expand All @@ -73,25 +73,36 @@ func SubtleCall(method string, args ...interface{}) (*js.Object, error) {
resCh := make(chan *js.Object, 1)
failCh := make(chan *js.Object, 1)

defer func() {
switch exc := recover().(type) {
case *js.Error:
err = exc
case nil:
break
default:
panic(exc)
}
}()

promise := SubtleCrypto.Call(method, args...)
promise.Call(
"then",
func(o *js.Object) { resCh <- o },
func(err *js.Object) { failCh <- err })

select {
case res := <-resCh:
return res, nil
case err := <-failCh:
switch err.Get("name").String() {
case jsres := <-resCh:
return jsres, nil
case jserr := <-failCh:
switch jserr.Get("name").String() {
case "DataError":
return nil, ErrWebCryptoDataError
case "NotSupportedError":
return nil, ErrWebCryptoNotSupportedError
case "OperationError":
return nil, ErrWebCryptoOperationError
default:
return nil, &js.Error{Object: err}
return nil, &js.Error{Object: jserr}
}
}
}
Expand Down