forked from rogchap/v8go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errors.go
64 lines (57 loc) · 1.74 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Copyright 2019 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
// #include <stdlib.h>
// #include "v8go.h"
import "C"
import (
"fmt"
"io"
"unsafe"
)
// JSError is an error that is returned if there is are any
// JavaScript exceptions handled in the context. When used with the fmt
// verb `%+v`, will output the JavaScript stack trace, if available.
type JSError struct {
Message string
Location string
StackTrace string
}
func newJSError(rtnErr C.RtnError) error {
err := &JSError{
Message: C.GoString(rtnErr.msg),
Location: C.GoString(rtnErr.location),
StackTrace: C.GoString(rtnErr.stack),
}
C.free(unsafe.Pointer(rtnErr.msg))
C.free(unsafe.Pointer(rtnErr.location))
C.free(unsafe.Pointer(rtnErr.stack))
return err
}
func (e *JSError) Error() string {
return e.Message
}
// Format implements the fmt.Formatter interface to provide a custom formatter
// primarily to output the javascript stack trace with %+v
func (e *JSError) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') && e.StackTrace != "" {
// The StackTrace starts with the Message, so only the former needs to be printed
io.WriteString(s, e.StackTrace)
// If it was a compile time error, then there wouldn't be a runtime stack trace,
// but StackTrace will still include the Message, making them equal. In this case,
// we want to include the Location where the compilation failed.
if e.StackTrace == e.Message && e.Location != "" {
fmt.Fprintf(s, " (at %s)", e.Location)
}
return
}
fallthrough
case 's':
io.WriteString(s, e.Message)
case 'q':
fmt.Fprintf(s, "%q", e.Message)
}
}