ScruffyDuck
ScruffyDuck

Reputation: 2666

How best to debug "The type initializer for xx class threw an exception"

I have one user reporting this exception. My research here and elsewhere suggests this is a static contructor error. The class concerned contains a number of static fields that are initialized. I assume it is one of these but I am not sure how to find it. The suggestion seems to be to include a try/catch block in the static contructor. As written there is no explicit static contructor.

I am thinking that I should write an explicit static constructor, move the initialization of the static fields into it and wrap them in the try/catch block. I know I could try this but the error does not arise for me and I would like to send a modded executable to the user to try. My application does log the errors so I should get a log from him if the exception is caught in the static constructor.

The relevant (I hope) part of the class is here (it is not actually my code but I can mod it as required):

 [Serializable]
    public class PText : PNode, ISerializable {

    //comments elided by edit for brevity
        #region Fields

        public const int PROPERTY_CODE_FONT = 1 << 18;
        public const int PROPERTY_CODE_TEXT = 1 << 17;
        public static Font DEFAULT_FONT = new Font("Arial", 12);
        protected static readonly object PROPERTY_KEY_FONT = new object();
        protected static readonly object PROPERTY_KEY_TEXT = new object(); 
        private static Graphics GRAPHICS = Graphics.FromImage(new Bitmap(1, 1));

        [NonSerialized]
        private Color brushColor;
        private bool constrainHeightToTextHeight = true;
        private bool constrainWidthToTextWidth = true;
        private Font font;

        [NonSerialized]
        private Color penColor;

        [NonSerialized]
        private StringFormat stringFormat = new StringFormat();
        private String text;

        [NonSerialized]
        private Brush textBrush;

        #endregion Fields

        #region Constructors
        public PText() {
            textBrush = Brushes.Black;
        }

        public PText(String aText)
            : this() {
            Text = aText;
        }

        protected PText(SerializationInfo info, StreamingContext context)
            : base(info, context) {
            textBrush = PUtil.ReadBrush(info, "textbrush");
            TextAlignment = (StringAlignment)info.GetValue("alignment", typeof(int));
        }

        #endregion Constructors
.......

Upvotes: 1

Views: 1491

Answers (2)

Andras Zoltan
Andras Zoltan

Reputation: 42363

The best way to debug, that requires minimal code-change (assuming this is a desktop app?) is probably to hook into the AppDomain.UnhandledException event - subscribe to it in the startup code in Program.cs and then you can catch any exception.

Base on the code you've actually posted, it's either:

public static Font DEFAULT_FONT = new Font("Arial", 12);

Or

private static Graphics GRAPHICS = Graphics.FromImage(new Bitmap(1, 1)); 

Given that only one user is reporting it, and if I'm right, - then logic dictates ('once you eliminate the impossible' and all that) it must be that they don't have the Arial font on their machine; as crazy as that sounds.

Or - as I've been rightly reminded (and why I qualified it as valid only based on the code you've posted) - it could also be a static defined in the PNode type or any anywhere else in the type hierarchy. What is the 'xx' class reported as in the exception?

Upvotes: 2

Kyle W
Kyle W

Reputation: 3752

To answer your question, the idea you had is good. Put a try/catch around the possible lines that are throwing, and then log the error before it becomes a TypeInitializationException.

Alternatively, change to use Lazy - this will change the exception to be where it is first accessed. This may or may not be useful for you, but it has helped me debug similar issues.

Upvotes: 2

Related Questions