package goja
import "github.com/dop251/goja/unistring"
const propNameStack = "stack"
type errorObject struct {
baseObject
stack []StackFrame
stackPropAdded bool
}
func (e *errorObject ) formatStack () String {
var b StringBuilder
val := writeErrorString (&b , e .val )
if val != nil {
b .WriteString (val )
}
b .WriteRune ('\n' )
for _ , frame := range e .stack {
b .writeASCII ("\tat " )
frame .WriteToValueBuilder (&b )
b .WriteRune ('\n' )
}
return b .String ()
}
func (e *errorObject ) addStackProp () Value {
if !e .stackPropAdded {
res := e ._putProp (propNameStack , e .formatStack (), true , false , true )
if len (e .propNames ) > 1 {
copy (e .propNames [1 :], e .propNames )
e .propNames [0 ] = propNameStack
}
e .stackPropAdded = true
return res
}
return nil
}
func (e *errorObject ) getStr (p unistring .String , receiver Value ) Value {
return e .getStrWithOwnProp (e .getOwnPropStr (p ), p , receiver )
}
func (e *errorObject ) getOwnPropStr (name unistring .String ) Value {
res := e .baseObject .getOwnPropStr (name )
if res == nil && name == propNameStack {
return e .addStackProp ()
}
return res
}
func (e *errorObject ) setOwnStr (name unistring .String , val Value , throw bool ) bool {
if name == propNameStack {
e .addStackProp ()
}
return e .baseObject .setOwnStr (name , val , throw )
}
func (e *errorObject ) setForeignStr (name unistring .String , val , receiver Value , throw bool ) (bool , bool ) {
return e ._setForeignStr (name , e .getOwnPropStr (name ), val , receiver , throw )
}
func (e *errorObject ) deleteStr (name unistring .String , throw bool ) bool {
if name == propNameStack {
e .addStackProp ()
}
return e .baseObject .deleteStr (name , throw )
}
func (e *errorObject ) defineOwnPropertyStr (name unistring .String , desc PropertyDescriptor , throw bool ) bool {
if name == propNameStack {
e .addStackProp ()
}
return e .baseObject .defineOwnPropertyStr (name , desc , throw )
}
func (e *errorObject ) hasOwnPropertyStr (name unistring .String ) bool {
if e .baseObject .hasOwnPropertyStr (name ) {
return true
}
return name == propNameStack && !e .stackPropAdded
}
func (e *errorObject ) stringKeys (all bool , accum []Value ) []Value {
if all && !e .stackPropAdded {
accum = append (accum , asciiString (propNameStack ))
}
return e .baseObject .stringKeys (all , accum )
}
func (e *errorObject ) iterateStringKeys () iterNextFunc {
e .addStackProp ()
return e .baseObject .iterateStringKeys ()
}
func (e *errorObject ) init () {
e .baseObject .init ()
vm := e .val .runtime .vm
e .stack = vm .captureStack (make ([]StackFrame , 0 , len (vm .callStack )+1 ), 0 )
}
func (r *Runtime ) newErrorObject (proto *Object , class string ) *errorObject {
obj := &Object {runtime : r }
o := &errorObject {
baseObject : baseObject {
class : class ,
val : obj ,
extensible : true ,
prototype : proto ,
},
}
obj .self = o
o .init ()
return o
}
func (r *Runtime ) builtin_Error (args []Value , proto *Object ) *Object {
obj := r .newErrorObject (proto , classError )
if len (args ) > 0 && args [0 ] != _undefined {
obj ._putProp ("message" , args [0 ].ToString (), true , false , true )
}
if len (args ) > 1 && args [1 ] != _undefined {
if options , ok := args [1 ].(*Object ); ok {
if options .hasProperty (asciiString ("cause" )) {
obj .defineOwnPropertyStr ("cause" , PropertyDescriptor {
Writable : FLAG_TRUE ,
Enumerable : FLAG_FALSE ,
Configurable : FLAG_TRUE ,
Value : options .Get ("cause" ),
}, true )
}
}
}
return obj .val
}
func (r *Runtime ) builtin_AggregateError (args []Value , proto *Object ) *Object {
obj := r .newErrorObject (proto , classError )
if len (args ) > 1 && args [1 ] != nil && args [1 ] != _undefined {
obj ._putProp ("message" , args [1 ].toString (), true , false , true )
}
var errors []Value
if len (args ) > 0 {
errors = r .iterableToList (args [0 ], nil )
}
obj ._putProp ("errors" , r .newArrayValues (errors ), true , false , true )
if len (args ) > 2 && args [2 ] != _undefined {
if options , ok := args [2 ].(*Object ); ok {
if options .hasProperty (asciiString ("cause" )) {
obj .defineOwnPropertyStr ("cause" , PropertyDescriptor {
Writable : FLAG_TRUE ,
Enumerable : FLAG_FALSE ,
Configurable : FLAG_TRUE ,
Value : options .Get ("cause" ),
}, true )
}
}
}
return obj .val
}
func writeErrorString(sb *StringBuilder , obj *Object ) String {
var nameStr , msgStr String
name := obj .self .getStr ("name" , nil )
if name == nil || name == _undefined {
nameStr = asciiString ("Error" )
} else {
nameStr = name .toString ()
}
msg := obj .self .getStr ("message" , nil )
if msg == nil || msg == _undefined {
msgStr = stringEmpty
} else {
msgStr = msg .toString ()
}
if nameStr .Length () == 0 {
return msgStr
}
if msgStr .Length () == 0 {
return nameStr
}
sb .WriteString (nameStr )
sb .WriteString (asciiString (": " ))
sb .WriteString (msgStr )
return nil
}
func (r *Runtime ) error_toString (call FunctionCall ) Value {
var sb StringBuilder
val := writeErrorString (&sb , r .toObject (call .This ))
if val != nil {
return val
}
return sb .String ()
}
func (r *Runtime ) createErrorPrototype (name String , ctor *Object ) *Object {
o := r .newBaseObject (r .getErrorPrototype (), classObject )
o ._putProp ("message" , stringEmpty , true , false , true )
o ._putProp ("name" , name , true , false , true )
o ._putProp ("constructor" , ctor , true , false , true )
return o .val
}
func (r *Runtime ) getErrorPrototype () *Object {
ret := r .global .ErrorPrototype
if ret == nil {
ret = r .NewObject ()
r .global .ErrorPrototype = ret
o := ret .self
o ._putProp ("message" , stringEmpty , true , false , true )
o ._putProp ("name" , stringError , true , false , true )
o ._putProp ("toString" , r .newNativeFunc (r .error_toString , "toString" , 0 ), true , false , true )
o ._putProp ("constructor" , r .getError (), true , false , true )
}
return ret
}
func (r *Runtime ) getError () *Object {
ret := r .global .Error
if ret == nil {
ret = &Object {runtime : r }
r .global .Error = ret
r .newNativeFuncConstruct (ret , r .builtin_Error , "Error" , r .getErrorPrototype (), 1 )
}
return ret
}
func (r *Runtime ) getAggregateError () *Object {
ret := r .global .AggregateError
if ret == nil {
ret = &Object {runtime : r }
r .global .AggregateError = ret
r .newNativeFuncConstructProto (ret , r .builtin_AggregateError , "AggregateError" , r .createErrorPrototype (stringAggregateError , ret ), r .getError (), 2 )
}
return ret
}
func (r *Runtime ) getTypeError () *Object {
ret := r .global .TypeError
if ret == nil {
ret = &Object {runtime : r }
r .global .TypeError = ret
r .newNativeFuncConstructProto (ret , r .builtin_Error , "TypeError" , r .createErrorPrototype (stringTypeError , ret ), r .getError (), 1 )
}
return ret
}
func (r *Runtime ) getReferenceError () *Object {
ret := r .global .ReferenceError
if ret == nil {
ret = &Object {runtime : r }
r .global .ReferenceError = ret
r .newNativeFuncConstructProto (ret , r .builtin_Error , "ReferenceError" , r .createErrorPrototype (stringReferenceError , ret ), r .getError (), 1 )
}
return ret
}
func (r *Runtime ) getSyntaxError () *Object {
ret := r .global .SyntaxError
if ret == nil {
ret = &Object {runtime : r }
r .global .SyntaxError = ret
r .newNativeFuncConstructProto (ret , r .builtin_Error , "SyntaxError" , r .createErrorPrototype (stringSyntaxError , ret ), r .getError (), 1 )
}
return ret
}
func (r *Runtime ) getRangeError () *Object {
ret := r .global .RangeError
if ret == nil {
ret = &Object {runtime : r }
r .global .RangeError = ret
r .newNativeFuncConstructProto (ret , r .builtin_Error , "RangeError" , r .createErrorPrototype (stringRangeError , ret ), r .getError (), 1 )
}
return ret
}
func (r *Runtime ) getEvalError () *Object {
ret := r .global .EvalError
if ret == nil {
ret = &Object {runtime : r }
r .global .EvalError = ret
r .newNativeFuncConstructProto (ret , r .builtin_Error , "EvalError" , r .createErrorPrototype (stringEvalError , ret ), r .getError (), 1 )
}
return ret
}
func (r *Runtime ) getURIError () *Object {
ret := r .global .URIError
if ret == nil {
ret = &Object {runtime : r }
r .global .URIError = ret
r .newNativeFuncConstructProto (ret , r .builtin_Error , "URIError" , r .createErrorPrototype (stringURIError , ret ), r .getError (), 1 )
}
return ret
}
func (r *Runtime ) getGoError () *Object {
ret := r .global .GoError
if ret == nil {
ret = &Object {runtime : r }
r .global .GoError = ret
r .newNativeFuncConstructProto (ret , r .builtin_Error , "GoError" , r .createErrorPrototype (stringGoError , ret ), r .getError (), 1 )
}
return ret
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .