Exceptions and static constructors.

B

BLUE

VS .NET 2003 CF
In this method I cannot catch exceptions thrown by Settings constructor (for
example FileNotFoundException) but only an OutOfMemory exception due to Get
returning void.
Why???



private void GtmForm_Load(object sender, System.EventArgs e)
{
try
{
this.idLength = uint.Parse(Settings.Get("idLength"));
}
catch(FileNotFoundException fnfEx)
{
MessageBox.Show(fnfEx.Message);
Application.Exit();
}
catch(XmlException xmlEx)
{
MessageBox.Show(xmlEx.Message + "\n" +
xmlEx.InnerException.Message);
Application.Exit();
}
catch(Exception ex)
{
MessageBox.Show("Error loading configuration file!\n" + ex.Message);
Application.Exit();
}

this.employeeAssetIdTextBox.Focus();
}



public class Settings
{
private static readonly string path;
private static readonly NameValueCollection appSettings;

static Settings()
{
path =
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
path += @"\Setting.xml";

if (!File.Exists(path))
{
throw new FileNotFoundException(path + " could not be found!");
}

appSettings = new NameValueCollection();
try
{
XmlTextReader appSettingsReader = new XmlTextReader(path);

while (appSettingsReader.Read())
{
if (appSettingsReader.NodeType == XmlNodeType.Element &&
appSettingsReader.AttributeCount == 2)
{
appSettings.Add(appSettingsReader.GetAttribute(0),
appSettingsReader.GetAttribute(1));
}
}
}
catch(XmlException e)
{
throw new XmlException("Error processing configuration
file!",e);
}
}

public static string Get(string key)
{
try
{
return appSettings.Get(key);
}
catch(FileNotFoundException)
{
throw new FileNotFoundException(path + " could not be found!");
}
catch(XmlException e)
{
throw new XmlException("Error processing configuration
file!",e);
}
}
}
 
J

Jon Skeet [C# MVP]

VS .NET 2003 CF
In this method I cannot catch exceptions thrown by Settings constructor (for
example FileNotFoundException) but only an OutOfMemory exception due to Get
returning void.
Why???

The static constructor will throw a TypeInitializationException with
the actual exception as an inner exception.

However, it's very bad form to do so much work within a static
constructor. For one thing, once a type has failed to load, you won't
be able to use it within that AppDomain, even if you "fix" whatever was
wrong.

You'd be better off setting appSettings within a "getter" property
using a lock for thread-safety. That way you don't need to worry about
any wrappers etc, you'll just get the normal exception.
 
B

BLUE

The static constructor will throw a TypeInitializationException

try
{
this.idLength = uint.Parse(Settings.Get("idLength"));
}
catch(Exception ex)
{
MessageBox.Show("Error loading configuration file!\n" + ex.Message);
Application.Exit();
}

Debugging this code the Exception type is OutOfMemory not
TypeInitializationException.
File loading or DB connections could be done (with exception management and
MessageBox showing errors) in form load event?
Or it would be better to do them while handling another event?

You'd be better off setting appSettings within a "getter" property using a
lock for thread-safety

Using a getter property that returns appSettings I have no more
encapsulation: I receive a collection instead of a string.
Using a getter property that returns a value I have no more indipendence
from the key name.
Using my Get method means loading the file each time I request a setting.
That's why I've done so.


Thanks,
Luigi.
 
J

Jon Skeet [C# MVP]

try
{
this.idLength = uint.Parse(Settings.Get("idLength"));
}
catch(Exception ex)
{
MessageBox.Show("Error loading configuration file!\n" + ex.Message);
Application.Exit();
}

Debugging this code the Exception type is OutOfMemory not
TypeInitializationException.

That's very strange - certainly on my box, I get a
TypeInitializationException.
File loading or DB connections could be done (with exception management and
MessageBox showing errors) in form load event?
Or it would be better to do them while handling another event?

I'd personally do it before even loading any forms, in the main method,
if the files not existing (or whatever) will basically mean that your
app can't start.
Using a getter property that returns appSettings I have no more
encapsulation: I receive a collection instead of a string.

No, you'd call the getter within Settings.Get and any other Settings
methods. It would be a private property. Sorry for not making that
clearer.
 
B

BLUE

No, you'd call the getter within Settings.Get and any other Settings
methods. It would be a private property. Sorry for not making that
clearer.

Than you very much!
Now it works!!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top