Skip to content

Commit ee034ba

Browse files
committed
Source code integration
1 parent 0820803 commit ee034ba

File tree

6 files changed

+143
-6
lines changed

6 files changed

+143
-6
lines changed

Runtime/Model/BacktraceData.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ public class BacktraceData
6767
[JsonProperty(PropertyName = "classifiers", NullValueHandling = NullValueHandling.Ignore)]
6868
public string[] Classifier;
6969

70+
/// <summary>
71+
/// Source code information - right now we support source code only for BacktraceUnhandledException exceptions.
72+
/// </summary>
73+
[JsonProperty(PropertyName = "sourceCode ")]
74+
internal BacktraceSourceCode SourceCode;
75+
7076
/// <summary>
7177
/// Get a path to report attachments
7278
/// </summary>
@@ -132,7 +138,8 @@ public string ToJson()
132138
{"classifiers", new JArray(Classifier)},
133139
{"attributes", Attributes.ToJson()},
134140
{"annotations", Annotation.ToJson()},
135-
{"threads", ThreadData == null ? null : ThreadData.ToJson()}
141+
{"threads", ThreadData == null ? null : ThreadData.ToJson()},
142+
{"sourceCode", SourceCode == null ? null : SourceCode.ToJson()}
136143
};
137144
return json.ToString();
138145
}
@@ -157,7 +164,8 @@ public static BacktraceData Deserialize(string json)
157164
Classifier = classfiers,
158165
Annotation = Annotations.Deserialize(@object["annotations"]),
159166
Attributes = BacktraceAttributes.Deserialize(@object["attributes"]),
160-
ThreadData = ThreadData.DeserializeThreadInformation(@object["threads"])
167+
ThreadData = ThreadData.DeserializeThreadInformation(@object["threads"]),
168+
SourceCode = BacktraceSourceCode.Deserialize(@object["sourceCode"]),
161169
};
162170
}
163171

@@ -169,6 +177,10 @@ private void SetThreadInformations()
169177
ThreadData = new ThreadData(Report.DiagnosticStack);
170178
ThreadInformations = ThreadData.ThreadInformations;
171179
MainThread = ThreadData.MainThread;
180+
if (Report.Exception is BacktraceUnhandledException)
181+
{
182+
SourceCode = (Report.Exception as BacktraceUnhandledException).SourceCode;
183+
}
172184
}
173185

174186
/// <summary>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Backtrace.Newtonsoft.Linq;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Backtrace.Unity.Model
9+
{
10+
public class BacktraceSourceCode
11+
{
12+
public string Id = Guid.NewGuid().ToString();
13+
public string Type { get; set; } = "Text";
14+
public string Title { get; set; } = "Log File";
15+
16+
public bool HighlightLine = false;
17+
public string Text { get; set; }
18+
19+
internal BacktraceJObject ToJson()
20+
{
21+
var json = new BacktraceJObject();
22+
json[Id.ToString()] = new BacktraceJObject()
23+
{
24+
["id"] = Id,
25+
["type"] = Type,
26+
["title"] = Title,
27+
["highlightLine"] = HighlightLine,
28+
["text"] = Text,
29+
};
30+
31+
return json;
32+
}
33+
34+
internal static BacktraceSourceCode Deserialize(JToken token)
35+
{
36+
if (token == null)
37+
{
38+
return null;
39+
}
40+
var data = token.FirstOrDefault();
41+
if (data == null)
42+
{
43+
return null;
44+
}
45+
var rawSourceCode = data.FirstOrDefault();
46+
var sourceCode = new BacktraceSourceCode()
47+
{
48+
Id = rawSourceCode.Value<string>("id"),
49+
Text = rawSourceCode.Value<string>("text"),
50+
Title = rawSourceCode.Value<string>("title"),
51+
Type = rawSourceCode.Value<string>("type")
52+
};
53+
return sourceCode;
54+
}
55+
}
56+
}

Runtime/Model/BacktraceSourceCode.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Model/BacktraceStackFrame.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,27 @@ public BacktraceJObject ToJson()
6161
var stackFrame = new BacktraceJObject
6262
{
6363
{"funcName", FunctionName},
64-
{"line", Line},
6564
{"il", Il},
6665
{"metadata_token", MemberInfo},
67-
{"column", Column},
66+
6867
{"address", ILOffset},
6968
{"library", Library}
7069
};
71-
//todo: source code information
70+
71+
if(Column != 0)
72+
{
73+
stackFrame["column"] = Column;
74+
}
75+
76+
if (Line != 0)
77+
{
78+
stackFrame["line"] = Line;
79+
}
80+
81+
if (!string.IsNullOrEmpty(SourceCode))
82+
{
83+
stackFrame["sourceCode"] = SourceCode;
84+
}
7285

7386
return stackFrame;
7487
}

Runtime/Model/BacktraceUnhandledException.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4+
using System.Linq;
45

56
namespace Backtrace.Unity.Model
67
{
@@ -38,12 +39,31 @@ public override string StackTrace
3839
}
3940

4041
public List<BacktraceStackFrame> StackFrames = new List<BacktraceStackFrame>();
42+
public BacktraceSourceCode SourceCode = null;
4143

4244
public BacktraceUnhandledException(string message, string stacktrace) : base(message)
4345
{
4446
_stacktrace = stacktrace;
4547
_message = message;
4648
ConvertStackFrames();
49+
CreateUnhandledExceptionLogInformation();
50+
}
51+
52+
/// <summary>
53+
/// Assign source code information to first stack frame of unhandled exception report
54+
/// </summary>
55+
private void CreateUnhandledExceptionLogInformation()
56+
{
57+
SourceCode = new BacktraceSourceCode()
58+
{
59+
Text = string.Format("Unity Exception:\n{0}\n{1}", _message, _stacktrace)
60+
};
61+
// assign log information to first stack frame
62+
if (StackFrames.Count == 0)
63+
{
64+
return;
65+
}
66+
StackFrames.First().SourceCode = SourceCode.Id.ToString();
4767
}
4868

4969
private void ConvertStackFrames()

Tests/Runtime/BacktraceReportTests.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,35 @@ public IEnumerator TestReportValues_ShouldAssignCorrectExceptionInformation_Exce
7272
Assert.AreEqual(reportAttributes["test_attribute"], report.Attributes["test_attribute"]);
7373
Assert.AreEqual(reportAttributes["temporary_attribute"], report.Attributes["temporary_attribute"]);
7474
Assert.AreEqual(reportAttributes["temporary_attribute_bool"], report.Attributes["temporary_attribute_bool"]);
75-
75+
7676
yield return null;
7777
}
7878

79+
[Test]
80+
public void TestReportSourceCode_UnhandledExceptionSourceCode_ExceptionShouldHaveSourceCode()
81+
{
82+
var message = "message";
83+
var stackTrace = "Startup.DoSomethingElse ()";
84+
var unhandledExceptionReport = new BacktraceUnhandledException(message, stackTrace);
85+
var report = new BacktraceReport(unhandledExceptionReport);
86+
var data = report.ToBacktraceData(null);
87+
Assert.IsNotNull(data.SourceCode);
88+
Assert.AreEqual("Text", data.SourceCode.Type);
89+
Assert.AreEqual("Log File", data.SourceCode.Title);
90+
// test unhandled exception text - based on unhandled exception text algorithm
91+
Assert.AreEqual(string.Format("Unity Exception:\n{0}\n{1}", message, stackTrace), data.SourceCode.Text);
92+
}
93+
94+
[Test]
95+
public void TestReportSourceCode_HandledExceptionSourceCode_ReportShouldntHaveReportSourceCode()
96+
{
97+
var message = "message";
98+
var unhandledExceptionReport = new Exception(message);
99+
var report = new BacktraceReport(unhandledExceptionReport);
100+
var data = report.ToBacktraceData(null);
101+
Assert.IsNull(data.SourceCode);
102+
}
103+
79104
private IEnumerator TestSerialization(BacktraceReport report)
80105
{
81106
var json = report.ToJson();

0 commit comments

Comments
 (0)