egametang/ET · error · Exception
to json error
Error message
to json error {obj.GetType().FullName}
{e} What it means
Thrown by ET.MongoHelper.ToJson(object) when the MongoDB BSON driver's obj.ToJson(defaultSettings) raises during JSON serialization. It wraps any inner failure into a single Exception whose Message embeds the target type FullName and the original exception text. Note: the rethrow at line 36 does NOT pass the original exception as InnerException (no ', e'), so the stack trace is lost and only the formatted string survives.
Solutions
- Inspect the embedded inner text in the message (the type FullName + inner message); fix the named type's serialization registration.
- Ensure the type has a registered serializer: BsonSerializer.RegisterSerializer(...) or a BsonClassMap, and for polymorphism add [BsonDiscriminator]/[BsonKnownTypes].
- If obj may be null, null-check before calling ToJson (the catch will itself NRE on obj.GetType()).
- Consider passing the inner exception: throw new Exception(..., e) so the real stack trace is preserved.
Example fix
// before
string s = MongoHelper.ToJson(maybeNullObj);
// after
if (maybeNullObj == null) return null;
try { return MongoHelper.ToJson(maybeNullObj); }
catch (Exception e) { Log.Error($"serialize {maybeNullObj.GetType()} failed: {e}"); throw; } Defensive patterns
Strategy: try-catch
Validate before calling
// validate before serialize
if (obj == null) throw new ArgumentNullException(nameof(obj));
if (!BsonSerializer.IsTypeRegistered(obj.GetType()))
throw new InvalidOperationException($"no bson serializer for {obj.GetType().FullName}"); Try / catch
try { return MongoHelper.ToJson(obj); }
catch (Exception e) { /* message already contains inner text; log obj type + e.Message */ Log.Error(e); throw; } Prevention
- Never pass null to MongoHelper.ToJson - the catch block NREs on obj.GetType().
- Register BsonClassMaps at startup for all serialized types.
- Add [BsonKnownTypes] on polymorphic bases.
When it happens
Trigger: Calling MongoHelper.ToJson(obj) on an object whose runtime type has no registered BsonClassMap/serializer, a type with an unserializable member (e.g. an interface or Dictionary with non-serializable key), a circular reference, or passing obj == null (which also makes the catch itself NullReference via obj.GetType()).
Common situations: Sharing entities/messages over JSON (network, logs, config dumps), serializing dynamically-typed or polymorphic objects without [BsonKnownTypes], migrating classes and forgetting to register class maps, or null args after a refactor.
Related errors
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/799ff58a6c800a2b.
Report an issue: GitHub.
Appendix: source
Thrown at Packages/cn.etetet.core/Scripts/Core/Share/Serialize/MongoHelper.cs:36
Indent = true,
IndentChars = "\t",
NewLineChars = "\n",
OutputMode = JsonOutputMode.Shell
};
public static string ToJson(object obj)
{
try
{
if (obj is ISupportInitialize supportInitialize)
{
supportInitialize.BeginInit();
}
return obj.ToJson(defaultSettings);
}
catch (Exception e)
{
throw new Exception($"to json error {obj.GetType().FullName}\n{e}");
}
}
public static string ToJson(object obj, JsonWriterSettings settings)
{
try
{
if (obj is ISupportInitialize supportInitialize)
{
supportInitialize.BeginInit();
}
return obj.ToJson(settings);
}
catch (Exception e)
{
throw new Exception($"to json error {obj.GetType().FullName}\n{e}");
}
}View on GitHub (pinned to 5cab01f7a8)