aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/robertkrimen/otto/error.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/robertkrimen/otto/error.go')
-rw-r--r--vendor/github.com/robertkrimen/otto/error.go252
1 files changed, 252 insertions, 0 deletions
diff --git a/vendor/github.com/robertkrimen/otto/error.go b/vendor/github.com/robertkrimen/otto/error.go
new file mode 100644
index 000000000..41a5c10e7
--- /dev/null
+++ b/vendor/github.com/robertkrimen/otto/error.go
@@ -0,0 +1,252 @@
+package otto
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/robertkrimen/otto/file"
+)
+
+type _exception struct {
+ value interface{}
+}
+
+func newException(value interface{}) *_exception {
+ return &_exception{
+ value: value,
+ }
+}
+
+func (self *_exception) eject() interface{} {
+ value := self.value
+ self.value = nil // Prevent Go from holding on to the value, whatever it is
+ return value
+}
+
+type _error struct {
+ name string
+ message string
+ trace []_frame
+
+ offset int
+}
+
+func (err _error) format() string {
+ if len(err.name) == 0 {
+ return err.message
+ }
+ if len(err.message) == 0 {
+ return err.name
+ }
+ return fmt.Sprintf("%s: %s", err.name, err.message)
+}
+
+func (err _error) formatWithStack() string {
+ str := err.format() + "\n"
+ for _, frame := range err.trace {
+ str += " at " + frame.location() + "\n"
+ }
+ return str
+}
+
+type _frame struct {
+ native bool
+ nativeFile string
+ nativeLine int
+ file *file.File
+ offset int
+ callee string
+}
+
+var (
+ nativeFrame = _frame{}
+)
+
+type _at int
+
+func (fr _frame) location() string {
+ str := "<unknown>"
+
+ switch {
+ case fr.native:
+ str = "<native code>"
+ if fr.nativeFile != "" && fr.nativeLine != 0 {
+ str = fmt.Sprintf("%s:%d", fr.nativeFile, fr.nativeLine)
+ }
+ case fr.file != nil:
+ if p := fr.file.Position(file.Idx(fr.offset)); p != nil {
+ path, line, column := p.Filename, p.Line, p.Column
+
+ if path == "" {
+ path = "<anonymous>"
+ }
+
+ str = fmt.Sprintf("%s:%d:%d", path, line, column)
+ }
+ }
+
+ if fr.callee != "" {
+ str = fmt.Sprintf("%s (%s)", fr.callee, str)
+ }
+
+ return str
+}
+
+// An Error represents a runtime error, e.g. a TypeError, a ReferenceError, etc.
+type Error struct {
+ _error
+}
+
+// Error returns a description of the error
+//
+// TypeError: 'def' is not a function
+//
+func (err Error) Error() string {
+ return err.format()
+}
+
+// String returns a description of the error and a trace of where the
+// error occurred.
+//
+// TypeError: 'def' is not a function
+// at xyz (<anonymous>:3:9)
+// at <anonymous>:7:1/
+//
+func (err Error) String() string {
+ return err.formatWithStack()
+}
+
+func (err _error) describe(format string, in ...interface{}) string {
+ return fmt.Sprintf(format, in...)
+}
+
+func (self _error) messageValue() Value {
+ if self.message == "" {
+ return Value{}
+ }
+ return toValue_string(self.message)
+}
+
+func (rt *_runtime) typeErrorResult(throw bool) bool {
+ if throw {
+ panic(rt.panicTypeError())
+ }
+ return false
+}
+
+func newError(rt *_runtime, name string, stackFramesToPop int, in ...interface{}) _error {
+ err := _error{
+ name: name,
+ offset: -1,
+ }
+ description := ""
+ length := len(in)
+
+ if rt != nil && rt.scope != nil {
+ scope := rt.scope
+
+ for i := 0; i < stackFramesToPop; i++ {
+ if scope.outer != nil {
+ scope = scope.outer
+ }
+ }
+
+ frame := scope.frame
+
+ if length > 0 {
+ if at, ok := in[length-1].(_at); ok {
+ in = in[0 : length-1]
+ if scope != nil {
+ frame.offset = int(at)
+ }
+ length--
+ }
+ if length > 0 {
+ description, in = in[0].(string), in[1:]
+ }
+ }
+
+ limit := rt.traceLimit
+
+ err.trace = append(err.trace, frame)
+ if scope != nil {
+ for scope = scope.outer; scope != nil; scope = scope.outer {
+ if limit--; limit == 0 {
+ break
+ }
+
+ if scope.frame.offset >= 0 {
+ err.trace = append(err.trace, scope.frame)
+ }
+ }
+ }
+ } else {
+ if length > 0 {
+ description, in = in[0].(string), in[1:]
+ }
+ }
+ err.message = err.describe(description, in...)
+
+ return err
+}
+
+func (rt *_runtime) panicTypeError(argumentList ...interface{}) *_exception {
+ return &_exception{
+ value: newError(rt, "TypeError", 0, argumentList...),
+ }
+}
+
+func (rt *_runtime) panicReferenceError(argumentList ...interface{}) *_exception {
+ return &_exception{
+ value: newError(rt, "ReferenceError", 0, argumentList...),
+ }
+}
+
+func (rt *_runtime) panicURIError(argumentList ...interface{}) *_exception {
+ return &_exception{
+ value: newError(rt, "URIError", 0, argumentList...),
+ }
+}
+
+func (rt *_runtime) panicSyntaxError(argumentList ...interface{}) *_exception {
+ return &_exception{
+ value: newError(rt, "SyntaxError", 0, argumentList...),
+ }
+}
+
+func (rt *_runtime) panicRangeError(argumentList ...interface{}) *_exception {
+ return &_exception{
+ value: newError(rt, "RangeError", 0, argumentList...),
+ }
+}
+
+func catchPanic(function func()) (err error) {
+ defer func() {
+ if caught := recover(); caught != nil {
+ if exception, ok := caught.(*_exception); ok {
+ caught = exception.eject()
+ }
+ switch caught := caught.(type) {
+ case *Error:
+ err = caught
+ return
+ case _error:
+ err = &Error{caught}
+ return
+ case Value:
+ if vl := caught._object(); vl != nil {
+ switch vl := vl.value.(type) {
+ case _error:
+ err = &Error{vl}
+ return
+ }
+ }
+ err = errors.New(caught.string())
+ return
+ }
+ panic(caught)
+ }
+ }()
+ function()
+ return nil
+}