egametang/ET · error · Exception

Serialize error {obj.GetType().FullName} {e}

Error message

Serialize error {obj.GetType().FullName}
{e}

What it means

Thrown by MongoHelper.Serialize(object) (line 92) wrapping obj.ToBson() failures. ToBson requires every member to have a BSON serializer; any gap (interface-typed field, unregistered concrete type, missing class map) raises here. Inner exception is NOT preserved (no ', e'), so only the formatted message (type FullName + inner text) is available.

Source

Thrown at Packages/cn.etetet.core/Scripts/Core/Share/Serialize/MongoHelper.cs:92

            catch (Exception e)
            {
                throw new Exception($"from json error: {str}\n{e}");
            }
        }

        public static byte[] Serialize(object obj)
        {
            try
            {
                if (obj is ISupportInitialize supportInitialize)
                {
                    supportInitialize.BeginInit();
                }
                return obj.ToBson();
            }
            catch (Exception e)
            {
                throw new Exception($"Serialize error {obj.GetType().FullName}\n{e}");
            }
        }

        public static void Serialize(object message, MemoryStream stream)
        {
            try
            {
                if (message is ISupportInitialize supportInitialize)
                {
                    supportInitialize.BeginInit();
                }

                using BsonBinaryWriter bsonWriter = new(stream, BsonBinaryWriterSettings.Defaults);
            
                BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter);
                BsonSerializationArgs args = default;
                args.NominalType = typeof (object);
                IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType);

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. From the message identify the failing type, then register its serializer/class map at startup.
  2. Add [BsonKnownTypes] / [BsonDiscriminator] to polymorphic members so ToBson can pick the concrete serializer.
  3. Avoid non-serializable members (interfaces, delegates, IntPtr); mark them [BsonIgnore].
  4. Null-check obj first.
  5. Patch helper to preserve InnerException.

Example fix

// before
byte[] data = MongoHelper.Serialize(msg);

// after
[BsonIgnoreExtraElements]
public class MyMsg
{
    public long Id;
    [BsonIgnore] public Action Callback; // excluded from bson
}
if (msg != null) data = MongoHelper.Serialize(msg);
Defensive patterns

Strategy: validation

Validate before calling

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.Serialize(obj); }
catch (Exception e) { Log.Error($"Serialize {obj?.GetType()} failed: {e}"); throw; }

Prevention

When it happens

Trigger: Serializing an object graph containing a member whose type lacks a registered BSON serializer, a polymorphic field without [BsonKnownTypes]/discriminator, an unsupported type (e.g. System.Type, delegates), or null obj (catch NREs on obj.GetType()).

Common situations: Network message serialization (the hot path for ET messages), saving entities to Mongo, adding a new field of an uncommon type, null after entity disposal.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/20241ca69cec75c7. Report an issue: GitHub.