Skip to content

Commit dbb5802

Browse files
Improve error handling on failure to open serialized file
Show extra message when there is no type trees And avoid large unhelpful callstack when printing out errors if it is general Unknown error
1 parent 700c361 commit dbb5802

7 files changed

Lines changed: 68 additions & 27 deletions

File tree

Analyzer/AnalyzerTool.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using UnityDataTools.Analyzer.SQLite.Parsers;
77
using UnityDataTools.Analyzer.SQLite.Parsers.Models;
88
using UnityDataTools.Analyzer.SQLite.Writers;
9+
using UnityDataTools.BinaryFormat;
10+
using UnityDataTools.FileSystem;
911

1012
namespace UnityDataTools.Analyzer;
1113

@@ -74,8 +76,21 @@ public int Analyze(
7476
ReportProgress(Path.GetRelativePath(path, file), i, files.Length);
7577
countSuccess++;
7678
}
79+
catch (SerializedFileOpenException e)
80+
{
81+
// Expected failure — the file content could not be parsed.
82+
// Don't print a stack trace; it adds no value for this known failure mode.
83+
EraseProgressLine();
84+
var relativePath = Path.GetRelativePath(path, file);
85+
Console.Error.WriteLine($"Failed to open: {relativePath}");
86+
var hint = SerializedFileDetector.GetOpenFailureHint(e.FilePath);
87+
if (hint != null)
88+
Console.Error.WriteLine(hint);
89+
countFailures++;
90+
}
7791
catch (Exception e)
7892
{
93+
// Unexpected failure (SQL error, I/O error, bug, etc.) — print full details.
7994
EraseProgressLine();
8095
var relativePath = Path.GetRelativePath(path, file);
8196
Console.Error.WriteLine($"Failed to process: {relativePath}");

TextDumper/TextDumperTool.cs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public int Dump(string path, string outputPath, bool skipLargeArrays, long objec
4949
Console.WriteLine("UnityDataTool only supports binary-format SerializedFiles.");
5050
return 1;
5151
}
52-
else if (SerializedFileDetector.TryDetectSerializedFile(path, out var fileInfo))
52+
else if (SerializedFileDetector.TryDetectSerializedFile(path, out _))
5353
{
5454
// The input is a binary SerializedFile; dump it directly.
5555
try
@@ -59,21 +59,20 @@ public int Dump(string path, string outputPath, bool skipLargeArrays, long objec
5959
OutputSerializedFile(path, objectId);
6060
}
6161
}
62-
catch (Exception e)
62+
catch (SerializedFileOpenException)
6363
{
64-
PrintExceptionIfUseful(e);
65-
66-
// Post-analysis: check if the failure is due to missing TypeTrees.
67-
if (SerializedFileDetector.TryParseMetadata(path, fileInfo, out var metadata, out _))
64+
var hint = SerializedFileDetector.GetOpenFailureHint(path);
65+
if (hint != null)
6866
{
69-
if (!metadata.EnableTypeTree)
70-
{
71-
Console.WriteLine();
72-
Console.WriteLine("Note: This file does not have TypeTrees and can only be opened if all the types it");
73-
Console.WriteLine("uses exactly match the types available inside the build of UnityFileSystemApi being used.");
74-
}
67+
Console.WriteLine();
68+
Console.WriteLine(hint);
7569
}
76-
70+
return 1;
71+
}
72+
catch (Exception e)
73+
{
74+
Console.WriteLine($"Error: {e.GetType()}: {e.Message}");
75+
Console.WriteLine(e.StackTrace);
7776
return 1;
7877
}
7978
}
@@ -86,26 +85,14 @@ public int Dump(string path, string outputPath, bool skipLargeArrays, long objec
8685
}
8786
catch (Exception e)
8887
{
89-
PrintExceptionIfUseful(e);
88+
Console.WriteLine($"Error: {e.GetType()}: {e.Message}");
89+
Console.WriteLine(e.StackTrace);
9090
return 1;
9191
}
9292

9393
return 0;
9494
}
9595

96-
static void PrintExceptionIfUseful(Exception e)
97-
{
98-
// Avoid printing noisy messages if it is just the generic "we don't know why it failed"
99-
// fallback in UnityFileSystem.HandleErrors
100-
if (e.GetType().ToString() != "System.Exception")
101-
Console.Write($"Error: {e.GetType()}: ");
102-
if (!e.Message.Contains("Unknown error"))
103-
Console.WriteLine(e.Message);
104-
var stackTrace = e.StackTrace;
105-
if (!stackTrace.Contains("UnityFileSystem.HandleErrors"))
106-
Console.WriteLine(e.StackTrace);
107-
}
108-
10996

11097
void RecursiveDump(TypeTreeNode node, ref long offset, int level, int arrayIndex = -1)
11198
{

UnityBinaryFormat/SerializedFileDetector.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,25 @@ public static bool TryParseMetadata(string filePath, SerializedFileInfo headerIn
594594
}
595595
}
596596

597+
/// <summary>
598+
/// Returns a diagnostic hint explaining why a SerializedFile may have failed to open,
599+
/// or null if no specific diagnosis is available.
600+
/// Currently detects the common case of missing TypeTrees (player builds compiled
601+
/// without type information, which the DLL reports as a generic unknown error).
602+
/// </summary>
603+
/// <param name="path">Real filesystem path to the file that failed to open.</param>
604+
public static string GetOpenFailureHint(string path)
605+
{
606+
if (TryDetectSerializedFile(path, out var fileInfo) &&
607+
TryParseMetadata(path, fileInfo, out var metadata, out _) &&
608+
!metadata.EnableTypeTree)
609+
{
610+
return "Note: This file does not have TypeTrees and can only be opened if all the " +
611+
"types it uses exactly match the types in the build of UnityFileSystemApi being used.";
612+
}
613+
return null;
614+
}
615+
597616
/// <summary>
598617
/// Parses the TypeTree and other arrays that are stored in the metadata,
599618
/// </summary>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
3+
namespace UnityDataTools.FileSystem;
4+
5+
/// <summary>
6+
/// Thrown when a SerializedFile cannot be opened, typically due to a content-related
7+
/// parsing failure (e.g. type mismatch, missing TypeTrees) rather than an I/O error.
8+
/// </summary>
9+
public class SerializedFileOpenException : Exception
10+
{
11+
public string FilePath { get; }
12+
13+
public SerializedFileOpenException(string filePath)
14+
: base($"Failed to open serialized file: \"{filePath}\"")
15+
=> FilePath = filePath;
16+
}

UnityFileSystem/UnityFileSystem.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ public static UnityFile OpenFile(string path)
4747
public static SerializedFile OpenSerializedFile(string path)
4848
{
4949
var r = DllWrapper.OpenSerializedFile(path, out var handle);
50+
51+
if (r == ReturnCode.UnknownError)
52+
throw new SerializedFileOpenException(path);
53+
5054
UnityFileSystem.HandleErrors(r, path);
5155

5256
return new SerializedFile() { m_Handle = handle };
6.42 MB
Binary file not shown.
34.5 MB
Binary file not shown.

0 commit comments

Comments
 (0)