Преглед на файлове

Included the location of the top stack frame in Exception.Error(). Fixes #29.

Dmitry Panov преди 8 години
родител
ревизия
a173fe93ff
променени са 2 файла, в които са добавени 42 реда и са изтрити 30 реда
  1. 41 29
      runtime.go
  2. 1 1
      runtime_test.go

+ 41 - 29
runtime.go

@@ -89,10 +89,41 @@ type stackFrame struct {
 	pc       int
 }
 
-func (f stackFrame) position() Position {
+func (f *stackFrame) position() Position {
 	return f.prg.src.Position(f.prg.sourceOffset(f.pc))
 }
 
+func (f *stackFrame) write(b *bytes.Buffer) {
+	if f.prg != nil {
+		if n := f.prg.funcName; n != "" {
+			b.WriteString(n)
+			b.WriteString(" (")
+		}
+		if n := f.prg.src.name; n != "" {
+			b.WriteString(n)
+		} else {
+			b.WriteString("<eval>")
+		}
+		b.WriteByte(':')
+		b.WriteString(f.position().String())
+		b.WriteByte('(')
+		b.WriteString(strconv.Itoa(f.pc))
+		b.WriteByte(')')
+		if f.prg.funcName != "" {
+			b.WriteByte(')')
+		}
+	} else {
+		if f.funcName != "" {
+			b.WriteString(f.funcName)
+			b.WriteString(" (")
+		}
+		b.WriteString("native")
+		if f.funcName != "" {
+			b.WriteByte(')')
+		}
+	}
+}
+
 type Exception struct {
 	val   Value
 	stack []stackFrame
@@ -118,34 +149,7 @@ func (e *Exception) String() string {
 	b.WriteByte('\n')
 	for _, frame := range e.stack {
 		b.WriteString("\tat ")
-		if frame.prg != nil {
-			if n := frame.prg.funcName; n != "" {
-				b.WriteString(n)
-				b.WriteString(" (")
-			}
-			if n := frame.prg.src.name; n != "" {
-				b.WriteString(n)
-			} else {
-				b.WriteString("<eval>")
-			}
-			b.WriteByte(':')
-			b.WriteString(frame.position().String())
-			b.WriteByte('(')
-			b.WriteString(strconv.Itoa(frame.pc))
-			b.WriteByte(')')
-			if frame.prg.funcName != "" {
-				b.WriteByte(')')
-			}
-		} else {
-			if frame.funcName != "" {
-				b.WriteString(frame.funcName)
-				b.WriteString(" (")
-			}
-			b.WriteString("native")
-			if frame.funcName != "" {
-				b.WriteByte(')')
-			}
-		}
+		frame.write(&b)
 		b.WriteByte('\n')
 	}
 	return b.String()
@@ -155,6 +159,14 @@ func (e *Exception) Error() string {
 	if e == nil || e.val == nil {
 		return "<nil>"
 	}
+	if len(e.stack) > 0 && (e.stack[0].prg != nil || e.stack[0].funcName != "") {
+		var b bytes.Buffer
+		b.WriteString(e.val.String())
+		b.WriteString(" at ")
+		e.stack[0].write(&b)
+		return b.String()
+	}
+
 	return e.val.String()
 }
 

+ 1 - 1
runtime_test.go

@@ -510,7 +510,7 @@ func TestRuntime_ExportToFuncThrow(t *testing.T) {
 
 	if _, err := fn("40"); err != nil {
 		if ex, ok := err.(*Exception); ok {
-			if msg := ex.Error(); msg != "Error: testing" {
+			if msg := ex.Error(); msg != "Error: testing at f (<eval>:3:9(4))" {
 				t.Fatalf("Msg: %q", msg)
 			}
 		} else {