Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial world.Error() implementation #1598

Merged
merged 9 commits into from
Jan 23, 2024
15 changes: 14 additions & 1 deletion OpenDreamRuntime/DreamManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,22 @@ public DreamValue LocateRef(string refString) {
return DreamValue.Null;
}

public void HandleException(Exception e) {
public void HandleException(Exception e, string msg = "", string file = "", int line = 0) {
if (string.IsNullOrEmpty(msg)) { // Just print the C# exception if we don't override the message
msg = e.Message;
}

LastDMException = e;
OnException?.Invoke(this, e);

// Invoke world.Error()
var obj =_objectTree.CreateObject<DreamObjectException>(_objectTree.Exception);
obj.Name = e.Message;
obj.Description = msg;
obj.Line = line;
obj.File = file;

WorldInstance.SpawnProc("Error", usr: null, new DreamValue(obj));
}
}

Expand Down
20 changes: 16 additions & 4 deletions OpenDreamRuntime/DreamThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,7 @@ public void AppendStackTrace(StringBuilder builder) {
{
builder.Append("(init)...");
}
else
{
else {
_current.AppendStackFrame(builder);
}
builder.AppendLine();
Expand All @@ -368,7 +367,7 @@ public void HandleException(Exception exception) {
_current?.Cancel();

var dreamMan = IoCManager.Resolve<DreamManager>();
dreamMan.HandleException(exception);


StringBuilder builder = new();
builder.AppendLine($"Exception occurred: {exception.Message}");
Expand All @@ -381,7 +380,20 @@ public void HandleException(Exception exception) {
builder.AppendLine(exception.ToString());
builder.AppendLine();

dreamMan.WriteWorldLog(builder.ToString(), LogLevel.Error);
var msg = builder.ToString();

// TODO: Defining world.Error() causes byond to no longer print exceptions to the log unless ..() is called
dreamMan.WriteWorldLog(msg, LogLevel.Error);

// Instantiate an /exception and invoke world.Error()
string file = string.Empty;
int line = 0;
if(_current is DMProcState dmProc) { // TODO: Cope with the other ProcStates
var source = dmProc.GetCurrentSource();
file = source.Item1;
line = source.Item2;
}
dreamMan.HandleException(exception, msg, file, line);

IoCManager.Resolve<IDreamDebugManager>().HandleException(this, exception);
}
Expand Down
2 changes: 2 additions & 0 deletions OpenDreamRuntime/Objects/DreamObjectTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ public DreamObject CreateObject(TreeEntry type) {
throw new Exception("Cannot create objects of type /client");
if (type.ObjectDefinition.IsSubtypeOf(Turf))
throw new Exception("New turfs must be created by the map manager");
if (type.ObjectDefinition.IsSubtypeOf(Exception))
return new DreamObjectException(type.ObjectDefinition);

return new DreamObject(type.ObjectDefinition);
}
Expand Down
29 changes: 29 additions & 0 deletions OpenDreamRuntime/Objects/Types/DreamObjectException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace OpenDreamRuntime.Objects.Types;

public sealed class DreamObjectException(DreamObjectDefinition objectDefinition) : DreamObject(objectDefinition) {
public string Name = string.Empty;
public string Description = string.Empty;
public string File = string.Empty;
public int Line = 0;

//TODO: Match the format of BYOND exceptions since SS13 does splittext and other things to extract data from exceptions

protected override bool TryGetVar(string varName, out DreamValue value) {
switch (varName) {
case "name":
value = new DreamValue(Name);
return true;
case "desc":
value = new DreamValue(Description);
return true;
case "file":
value = new DreamValue(File);
return true;
case "line":
value = new DreamValue(Line);
return true;
default:
return base.TryGetVar(varName, out value);
}
}
}
4 changes: 4 additions & 0 deletions OpenDreamRuntime/Procs/DMProc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ public override void AppendStackFrame(StringBuilder builder) {
builder.Append(Proc.GetSourceAtOffset(_pc - 1).Line);
}

public (string, int) GetCurrentSource() {
return Proc.GetSourceAtOffset(_pc - 1);
}

public void Jump(int position) {
_pc = position;
}
Expand Down
Loading