Skip to content

Commit

Permalink
ApplicationEngine helper to get engine error info (#3541)
Browse files Browse the repository at this point in the history
* helper to get engine error info

* cancel try

* Update src/Neo/SmartContract/ApplicationEngine.Helper.cs

Co-authored-by: Shargon <[email protected]>

* standalone method to get exception stack trace and message

* always return string

---------

Co-authored-by: Jimmy <[email protected]>
Co-authored-by: Shargon <[email protected]>
  • Loading branch information
3 people authored Oct 23, 2024
1 parent 16bde11 commit 6d7ea43
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/Neo/SmartContract/ApplicationEngine.Helper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// ApplicationEngine.Helper.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.SmartContract.Native;
using Neo.VM;
using System;
using System.Linq;
using System.Text;

namespace Neo.SmartContract
{
public partial class ApplicationEngine : ExecutionEngine
{
public string GetEngineStackInfoOnFault(bool exceptionStackTrace = true, bool exceptionMessage = true)
{
if (State != VMState.FAULT || FaultException == null)
return "";
StringBuilder traceback = new();
if (CallingScriptHash != null)
traceback.AppendLine($"CallingScriptHash={CallingScriptHash}[{NativeContract.ContractManagement.GetContract(SnapshotCache, CallingScriptHash)?.Manifest.Name}]");
traceback.AppendLine($"CurrentScriptHash={CurrentScriptHash}[{NativeContract.ContractManagement.GetContract(SnapshotCache, CurrentScriptHash)?.Manifest.Name}]");
traceback.AppendLine($"EntryScriptHash={EntryScriptHash}");

foreach (ExecutionContext context in InvocationStack.Reverse())
{
UInt160 contextScriptHash = context.GetScriptHash();
string contextContractName = NativeContract.ContractManagement.GetContract(SnapshotCache, contextScriptHash)?.Manifest.Name;
traceback.AppendLine($"\tInstructionPointer={context.InstructionPointer}, OpCode {context.CurrentInstruction?.OpCode}, Script Length={context.Script.Length} {contextScriptHash}[{contextContractName}]");
}
traceback.Append(GetEngineExceptionInfo(exceptionStackTrace: exceptionStackTrace, exceptionMessage: exceptionMessage));

return traceback.ToString();
}

public string GetEngineExceptionInfo(bool exceptionStackTrace = true, bool exceptionMessage = true)
{
if (State != VMState.FAULT || FaultException == null)
return "";
StringBuilder traceback = new();
Exception baseException = FaultException.GetBaseException();
if (exceptionStackTrace)
traceback.AppendLine(baseException.StackTrace);
if (exceptionMessage)
traceback.AppendLine(baseException.Message);
return traceback.ToString();
}
}
}
7 changes: 7 additions & 0 deletions tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,15 @@ public void TestSystem_Contract_Call_Permissions()
};
var currentScriptHash = engine.EntryScriptHash;

Assert.AreEqual("", engine.GetEngineStackInfoOnFault());
Assert.AreEqual(VMState.FAULT, engine.Execute());
Assert.IsTrue(engine.FaultException.ToString().Contains($"Cannot Call Method disallowed Of Contract {scriptHash.ToString()}"));
string traceback = engine.GetEngineStackInfoOnFault();
Assert.IsTrue(traceback.Contains($"Cannot Call Method disallowed Of Contract {scriptHash.ToString()}"));
Assert.IsTrue(traceback.Contains("CurrentScriptHash"));
Assert.IsTrue(traceback.Contains("EntryScriptHash"));
Assert.IsTrue(traceback.Contains("InstructionPointer"));
Assert.IsTrue(traceback.Contains("OpCode SYSCALL, Script Length="));
}

// Allowed method call.
Expand Down

0 comments on commit 6d7ea43

Please sign in to comment.