Ver Fonte

improve: error message behavior

Akeit0 há 6 meses atrás
pai
commit
a2967cd5cc
3 ficheiros alterados com 68 adições e 7 exclusões
  1. 47 1
      src/Lua/Exceptions.cs
  2. 6 2
      src/Lua/Runtime/Tracebacks.cs
  3. 15 4
      src/Lua/Standard/BasicLibrary.cs

+ 47 - 1
src/Lua/Exceptions.cs

@@ -87,7 +87,7 @@ public class LuaRuntimeException : Exception, ILuaTracebackBuildable
         Thread = thread;
     }
 
-    public LuaRuntimeException(LuaThread? thread, LuaValue errorObject)
+    public LuaRuntimeException(LuaThread? thread, LuaValue errorObject, int level = 1)
     {
         if (thread != null)
         {
@@ -99,8 +99,11 @@ public class LuaRuntimeException : Exception, ILuaTracebackBuildable
         Thread = thread;
 
         ErrorObject = errorObject;
+        this.level = level;
     }
 
+    int level = 1;
+
     Traceback? luaTraceback;
 
     public Traceback? LuaTraceback
@@ -329,6 +332,49 @@ public class LuaRuntimeException : Exception, ILuaTracebackBuildable
         Thread = null;
     }
 
+    internal string MinimalMessage()
+    {
+        var message = InnerException?.ToString() ?? ErrorObject.ToString();
+        if (level <= 0)
+        {
+            return message;
+        }
+
+        if (luaTraceback == null)
+        {
+            if (Thread != null)
+            {
+                var callStack = Thread.ExceptionTrace.AsSpan();
+                level = Math.Min(level, callStack.Length + 1);
+                callStack = callStack[(level - 1)..];
+                if (callStack.IsEmpty)
+                {
+                    return ErrorObject.ToString();
+                }
+
+                {
+                    var pooledList = new PooledList<char>(64);
+                    pooledList.Clear();
+                    try
+                    {
+                        Traceback.WriteLastLuaTrace(callStack, ref pooledList);
+                        if (pooledList.Length != 0) pooledList.AddRange(": ");
+                        pooledList.AddRange(message);
+                        return pooledList.AsSpan().ToString();
+                    }
+                    finally
+                    {
+                        pooledList.Dispose();
+                    }
+                }
+            }
+
+            return message;
+        }
+
+        return CreateMessage(luaTraceback, message);
+    }
+
     public override string Message
     {
         get

+ 6 - 2
src/Lua/Runtime/Tracebacks.cs

@@ -10,11 +10,10 @@ public class Traceback(LuaState state, ReadOnlySpan<CallStackFrame> stackFrames)
     readonly CallStackFrame[] stackFramesArray = stackFrames.ToArray();
     public ReadOnlySpan<CallStackFrame> StackFrames => stackFramesArray;
 
-    internal void WriteLastLuaTrace(ref PooledList<char> list)
+    internal static void WriteLastLuaTrace(ReadOnlySpan<CallStackFrame> stackFrames, ref PooledList<char> list)
     {
         var intFormatBuffer = (stackalloc char[15]);
         var shortSourceBuffer = (stackalloc char[59]);
-        var stackFrames = StackFrames;
         for (var index = stackFrames.Length - 1; index >= 1; index--)
         {
             LuaFunction lastFunc = stackFrames[index - 1].Function;
@@ -40,6 +39,11 @@ public class Traceback(LuaState state, ReadOnlySpan<CallStackFrame> stackFrames)
         }
     }
 
+    internal void WriteLastLuaTrace(ref PooledList<char> list)
+    {
+        WriteLastLuaTrace(StackFrames, ref list);
+    }
+
     public int LastLine
     {
         get

+ 15 - 4
src/Lua/Standard/BasicLibrary.cs

@@ -99,8 +99,11 @@ public sealed class BasicLibrary
         var value = context.ArgumentCount == 0
             ? LuaValue.Nil
             : context.Arguments[0];
+        var level = context.HasArgument(1)
+            ? context.GetArgument<int>(1)
+            : 1;
 
-        throw new LuaRuntimeException(context.Thread, value);
+        throw new LuaRuntimeException(context.Thread, value, level);
     }
 
     public ValueTask<int> GetMetatable(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
@@ -198,7 +201,7 @@ public sealed class BasicLibrary
             }
             else
             {
-                LuaRuntimeException.BadArgument(context.Thread, 1,[LuaValueType.String,LuaValueType.Function],arg0.Type);
+                LuaRuntimeException.BadArgument(context.Thread, 1, [LuaValueType.String, LuaValueType.Function], arg0.Type);
                 return default; // dummy
             }
         }
@@ -263,8 +266,16 @@ public sealed class BasicLibrary
                 case OperationCanceledException:
                     throw new LuaCanceledException(context.Thread, cancellationToken, ex);
                 case LuaRuntimeException luaEx:
-                    luaEx.Forget();
-                    return context.Return(false, luaEx.ErrorObject);
+                    {
+                        if (luaEx.ErrorObject.Type == LuaValueType.Nil)
+                        {
+                            return context.Return(false, LuaValue.Nil);
+                        }
+                        using var builder = new PooledList<char>();
+                        var message = luaEx.MinimalMessage();
+                        luaEx.Forget();
+                        return context.Return(false, message);
+                    }
                 default:
                     return context.Return(false, ex.Message);
             }