-
-
Notifications
You must be signed in to change notification settings - Fork 225
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Exception type and New*Error constructors.
- Loading branch information
Showing
6 changed files
with
283 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright 2021 Roger Chapman and the v8go contributors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package v8go | ||
|
||
import ( | ||
// #include <stdlib.h> | ||
// #include "v8go.h" | ||
"C" | ||
|
||
"fmt" | ||
"unsafe" | ||
) | ||
|
||
// NewRangeError creates a RangeError. | ||
func NewRangeError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_RANGE, msg) | ||
} | ||
|
||
// NewReferenceError creates a ReferenceError. | ||
func NewReferenceError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_REFERENCE, msg) | ||
} | ||
|
||
// NewSyntaxError creates a SyntaxError. | ||
func NewSyntaxError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_SYNTAX, msg) | ||
} | ||
|
||
// NewTypeError creates a TypeError. | ||
func NewTypeError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_TYPE, msg) | ||
} | ||
|
||
// NewWasmCompileError creates a WasmCompileError. | ||
func NewWasmCompileError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_WASM_COMPILE, msg) | ||
} | ||
|
||
// NewWasmLinkError creates a WasmLinkError. | ||
func NewWasmLinkError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_WASM_LINK, msg) | ||
} | ||
|
||
// NewWasmRuntimeError creates a WasmRuntimeError. | ||
func NewWasmRuntimeError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_WASM_RUNTIME, msg) | ||
} | ||
|
||
// NewError creates an Error, which is the common thing to throw from | ||
// user code. | ||
func NewError(iso *Isolate, msg string) *Exception { | ||
return newExceptionError(iso, C.ERROR_GENERIC, msg) | ||
} | ||
|
||
func newExceptionError(iso *Isolate, typ C.ErrorTypeIndex, msg string) *Exception { | ||
cmsg := C.CString(msg) | ||
defer C.free(unsafe.Pointer(cmsg)) | ||
eptr := C.NewValueError(iso.ptr, typ, cmsg) | ||
if eptr == nil { | ||
panic(fmt.Errorf("invalid error type index: %d", typ)) | ||
} | ||
return &Exception{&Value{ptr: eptr}} | ||
} | ||
|
||
// An Exception is a JavaScript exception. | ||
type Exception struct { | ||
*Value | ||
} | ||
|
||
// value implements Valuer. | ||
func (e *Exception) value() *Value { | ||
return e.Value | ||
} | ||
|
||
// Error implements error. | ||
func (e *Exception) Error() string { | ||
return e.String() | ||
} | ||
|
||
// As provides support for errors.As. | ||
func (e *Exception) As(target interface{}) bool { | ||
ep, ok := target.(**Exception) | ||
if !ok { | ||
return false | ||
} | ||
*ep = e | ||
return true | ||
} | ||
|
||
// Is provides support for errors.Is. | ||
func (e *Exception) Is(err error) bool { | ||
eerr, ok := err.(*Exception) | ||
if !ok { | ||
return false | ||
} | ||
return eerr.String() == e.String() | ||
} | ||
|
||
// String implements fmt.Stringer. | ||
func (e *Exception) String() string { | ||
if e.Value == nil { | ||
return "<nil>" | ||
} | ||
s := C.ExceptionGetMessageString(e.ptr) | ||
defer C.free(unsafe.Pointer(s)) | ||
return C.GoString(s) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright 2021 Roger Chapman and the v8go contributors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
package v8go_test | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
"testing" | ||
|
||
v8 "rogchap.com/v8go" | ||
) | ||
|
||
func TestNewError(t *testing.T) { | ||
t.Parallel() | ||
|
||
tsts := []struct { | ||
New func(*v8.Isolate, string) *v8.Exception | ||
WantType string | ||
}{ | ||
{v8.NewRangeError, "RangeError"}, | ||
{v8.NewReferenceError, "ReferenceError"}, | ||
{v8.NewSyntaxError, "SyntaxError"}, | ||
{v8.NewTypeError, "TypeError"}, | ||
{v8.NewWasmCompileError, "CompileError"}, | ||
{v8.NewWasmLinkError, "LinkError"}, | ||
{v8.NewWasmRuntimeError, "RuntimeError"}, | ||
{v8.NewError, "Error"}, | ||
} | ||
for _, tst := range tsts { | ||
t.Run(tst.WantType, func(t *testing.T) { | ||
iso := v8.NewIsolate() | ||
defer iso.Dispose() | ||
|
||
got := tst.New(iso, "amessage") | ||
if !got.IsNativeError() { | ||
t.Error("IsNativeError returned false, want true") | ||
} | ||
if got := got.Error(); !strings.Contains(got, " "+tst.WantType+":") { | ||
t.Errorf("Error(): got %q, want containing %q", got, tst.WantType) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestExceptionAs(t *testing.T) { | ||
iso := v8.NewIsolate() | ||
defer iso.Dispose() | ||
|
||
want := v8.NewRangeError(iso, "faked error") | ||
|
||
var got *v8.Exception | ||
if !want.As(&got) { | ||
t.Fatalf("As failed") | ||
} | ||
|
||
if got != want { | ||
t.Errorf("As: got %#v, want %#v", got, want) | ||
} | ||
} | ||
|
||
func TestExceptionIs(t *testing.T) { | ||
iso := v8.NewIsolate() | ||
defer iso.Dispose() | ||
|
||
t.Run("ok", func(t *testing.T) { | ||
ex := v8.NewRangeError(iso, "faked error") | ||
if !ex.Is(v8.NewRangeError(iso, "faked error")) { | ||
t.Fatalf("Is: got false, want true") | ||
} | ||
}) | ||
|
||
t.Run("notok", func(t *testing.T) { | ||
if (&v8.Exception{}).Is(errors.New("other error")) { | ||
t.Fatalf("Is: got true, want false") | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters