1
0
mirror of https://github.com/robertkrimen/otto synced 2025-09-28 18:45:22 +08:00
otto/error.go
2012-10-11 21:44:56 -07:00

152 lines
3.3 KiB
Go

package otto
import (
"fmt"
"errors"
)
type _error struct {
Name string
Message string
Line int // Hackish -- line where the error/exception occurred
}
var messageDetail map[string]string = map[string]string{
"notDefined": "%v is not defined",
}
func messageFromDescription(description string, argumentList... interface{}) string {
message := messageDetail[description]
if message == "" {
message = description
}
message = fmt.Sprintf(message, argumentList...)
return message
}
func (self _error) MessageValue() Value {
if self.Message == "" {
return UndefinedValue()
}
return toValue(self.Message)
}
func (self _error) String() string {
if len(self.Name) == 0 {
return self.Message
}
if len(self.Message) == 0 {
return self.Name
}
return fmt.Sprintf("%s: %s", self.Name, self.Message)
}
func newError(name string, argumentList... interface{}) _error {
description := ""
var node _node = nil
length := len(argumentList)
if length > 0 {
if node, _ = argumentList[length-1].(_node); node != nil || argumentList[length-1] == nil {
argumentList = argumentList[0:length-1]
length -= 1
}
if length > 0 {
description, argumentList = argumentList[0].(string), argumentList[1:]
}
}
error := _error{
Name: name,
Message: messageFromDescription(description, argumentList...),
Line: -1,
}
if node != nil {
error.Line = node.position()
}
return error
}
func newReferenceError(argumentList... interface{}) _error {
return newError("ReferenceError", argumentList...)
}
func newTypeError(argumentList... interface{}) _error {
return newError("TypeError", argumentList...)
}
func newRangeError(argumentList... interface{}) _error {
return newError("RangeError", argumentList...)
}
func newSyntaxError(argumentList... interface{}) _error {
return newError("URIError", argumentList...)
}
func newURIError(argumentList... interface{}) _error {
return newError("URIError", argumentList...)
}
func typeErrorResult(throw bool) bool {
if throw {
panic(newTypeError())
}
return false
}
func catchPanic(function func()) (err error) {
defer func(){
if caught := recover(); caught != nil {
switch caught := caught.(type) {
case *_syntaxError:
err = errors.New(fmt.Sprintf("%s (line %d)", caught.String(), caught.Line + 0))
return
case _error:
if caught.Line == -1 {
err = errors.New(caught.String())
} else {
// We're 0-based (for now), hence the + 1
err = errors.New(fmt.Sprintf("%s (line %d)", caught.String(), caught.Line + 1))
}
return
case _result:
if caught.Kind == resultThrow {
err = errors.New(toString(caught.Value))
} else {
// TODO Report this better
err = errors.New("Here be dragons!")
}
return
}
panic(caught)
}
}()
function()
return nil
}
// SyntaxError
type _syntaxError struct {
Message string
Line int
Column int
Character int
}
func (self _syntaxError) String() string {
name := "SyntaxError"
if len(self.Message) == 0 {
return name
}
return fmt.Sprintf("%s: %s", name, self.Message)
}
func (self _token) newSyntaxError(description string, argumentList... interface{}) *_syntaxError {
return &_syntaxError{
Message: messageFromDescription(description, argumentList...),
Line: self.Line,
Column: self.Column,
Character: self.Character,
}
}