0

I have bountified a question that kind of morphed into this question; IOW, this is a more concise and understandable statement of the precise problem, but is very similar to Update 8 there.

Basically, mnuSendINV_Click() calls SendInventoryData(), which calls getDataAsXMLFromTable(), which throws the NRE.

More specifically, here is the code in context:

private void mnuSendINV_Click(object sender, EventArgs e)
{
    SendInventoryData();
}    

private void SendInventoryData()
{
    String siteNum = String.Empty;
    ArrayList sbInventories = new ArrayList();
    foreach (String tbl in listboxWork.Items)
    {
        // Ignore CCR tables; just get INV tables
        if (tbl.IndexOf("CCR") >-1) continue;
        String tblName = getTableNameForInventoryName(tbl);
        siteNum = getSiteNumberFromInventoryName(tbl);
        sbInventories.Add(tblName);
    }
    foreach (string tbl in sbInventories) 
    {
        string strData = getDataAsXMLFromTable(tbl, "003"); 
        . . .
    }
}

private String getDataAsXMLFromTable(String tableName, String siteNum)
{
    string xmlOutput = String.Empty;
    // data/xml fields
    String lineId;
    String refNum;
    . . .
    String newItem;

    String paddedSiteNum = Prepad(3, siteNum);
    string connStr = String.Format("Data Source=\"\\My Documents\\HHSDB{0}.SDF\"", paddedSiteNum);
    String qry = String.Format("SELECT * FROM {0}", tableName);
    MessageBox.Show(String.Format("connstr is {0}; qry is {1}", connStr, qry));
    SqlCeConnection sqlceConn;
    SqlCeCommand sqlceCmd;
    try
    {
        sqlceConn = new SqlCeConnection(connStr);
        sqlceCmd = new SqlCeCommand(qry, sqlceConn);
        sqlceCmd.CommandType = CommandType.Text;
        MessageBox.Show("Made it just before conn.Open()"); // <= I see this
        if ((null != sqlceConn) && (!sqlceConn.State.Equals(ConnectionState.Open)))
        {
            MessageBox.Show("Will try to Open"); // <= I see this
            sqlceConn.Open(); // <= This is where the world explodes
        }
        MessageBox.Show("Made it just after conn.Open()"); // <= I don't see this/make it to here; I see the NRE instead
        SqlCeDataReader dtr = sqlceCmd.ExecuteReader(CommandBehavior.Default);
        XmlDocument doc = new XmlDocument();
        XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
        doc.AppendChild(dec);// Create the root element
        XmlElement root = doc.CreateElement("Command");
        doc.AppendChild(root);

        try
        {
            while (dtr.Read())
            {
                // outer INV
                XmlElement invRec = doc.CreateElement("INV");

                // Line ID
                lineId = dtr["line_id"].ToString();
                XmlElement _lineId = doc.CreateElement("line_id");
                _lineId.InnerText = lineId;
                invRec.AppendChild(_lineId);

                // Ref Num
                refNum = dtr["ref_no"].ToString();
                XmlElement _refNum = doc.CreateElement("ref_no");
                _refNum.InnerText = refNum;
                invRec.AppendChild(_refNum);

                . . .

                // New Item
                newItem = dtr["new_item"].ToString();
                XmlElement _new_item = doc.CreateElement("new_item");
                _new_item.InnerText = newItem;
                invRec.AppendChild(_new_item);

                root.AppendChild(invRec);
            }
        }
        finally
        {
            xmlOutput = doc.OuterXml;
            dtr.Close();
            if (sqlceCmd.Connection.State == ConnectionState.Open)
            {
                sqlceCmd.Connection.Close();
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(String.Format("inner ex is {0}", ex.InnerException.ToString()));
        SSCS.ExceptionHandler(ex, "frmCentral.getDataAsXMLFromTable()");
    }
    return xmlOutput;
} //getDataAsXMLFromTable

Note: With this code, I see:

0) "connstr is Data Source="\My Documents\HHSDB003.SDF"; qry is SELECT * FROM INV12262006091415"
1) "Made it just before conn.open"
2) "Will try to open"
3) "Exception: Null Reference Exception"

INV12262006091415 does exist in HHSDB003.SDF

UPDATE

In response to Alexei's suspicion, here is the file in question on the device:

enter image description here

The .exe is in \Program Files\HHS

UPDATE 2

For clever neologism (seems to be no "StackTrace" available on the exception class):

enter image description here

UPDATE 3

StackTrace unavailable; compile fails with "'System.Exception' does not contain a definition for 'StackTrace'" and reds up:

enter image description here

UPDATE 4

I tried daniele3004's suggestion, with this basic code:

private void menuItemTestSendingXML_Click(object sender, System.EventArgs e)
{
    // If one of the below works, try it with the String.Format() jazz
    //string connStr = "Data Source=\"\\My Documents\\HHSDB003.SDF"; <= NRE, without a catch block
    string connStr = @"Data Source= \\My Documents\\HHSDB003.SDF"; // NRE with a catch block IF InnerException not first checked for null
    //string connStr = @"Data Source= \\My Documents\HHSDB003.SDF";
    //string connStr = "Data Source= \\My Documents\\HHSDB003.SDF";
    //string connStr = "Data Source= \\\My Documents\\HHSDB003.SDF";

    SqlCeConnection conn = null;

    try
    {
        try
        {
            conn = new SqlCeConnection(connStr);
            conn.Open();
            MessageBox.Show("it must have opened okay");
        }
        finally
        {
            conn.Close();
        }
    }
    catch (Exception ex)
    {
        if (null == ex.InnerException)
        {
            MessageBox.Show("inner Ex is null");
        }
        MessageBox.Show(String.Format("msg is {0}", ex.Message));
    }
}

What I see so far (I still have to test the other connStr options) is:

"InnerEx is null"
"msg is " // [ex.Message is blank]

If there is an exception (and there is, because I reach the catch block), why is InnerException null?

UPDATE 5

None of my attempts work (note the comments):

//string connStr = "Data Source=\"\\My Documents\\HHSDB003.SDF"; <= NRE
//string connStr = @"Data Source= \\My Documents\\HHSDB003.SDF"; // No NRE, but exception
//string connStr = @"Data Source= \\My Documents\HHSDB003.SDF"; // "inner ex is null; msg is [blank]
//string connStr = "Data Source= \\My Documents\\HHSDB003.SDF"; // ""
//string connStr = "Data Source= \\\My Documents\\HHSDB003.SDF"; <= won't even compile ("unrecognized escape sequence")
//string connStr = @"Data Source= My Documents\HHSDB003.SDF"; // "inner ex is null; msg is [blank]
//string connStr = "Data Source= My Documents\HHSDB003.SDF"; <= won't even compile ("unrecognized escape sequence")
string connStr = "Data Source= My Documents\\HHSDB003.SDF"; // "inner ex is null; msg is [blank]

I'm assuming there's something wrong with my connStr, but how else is it to be done?

UPDATE 6

Okay, I found this code by jp2code here:

SqlCeConnection conn = new SqlCeConnection(@"Data Source=/My Documents/HHSDB003.sdf;");
try
{
    conn.Open();
    MessageBox.Show("Connection!");
}
catch (SqlCeException ee)  // <- Notice the use of SqlCeException to read your errors
{
    SqlCeErrorCollection errorCollection = ee.Errors;

    StringBuilder bld = new StringBuilder();
    Exception inner = ee.InnerException;

    if (null != inner) 
    {
        MessageBox.Show("Inner Exception: " + inner.ToString());
    }
    // Enumerate the errors to a message box.
    foreach (SqlCeError err in errorCollection) 
    {
        bld.Append("\n Error Code: " + err.HResult.ToString("X")); 
        bld.Append("\n Message   : " + err.Message);
        bld.Append("\n Minor Err.: " + err.NativeError);
        bld.Append("\n Source    : " + err.Source);

        // Enumerate each numeric parameter for the error.
        foreach (int numPar in err.NumericErrorParameters) 
        {
            if (0 != numPar) bld.Append("\n Num. Par. : " + numPar);
        }

        // Enumerate each string parameter for the error.
        foreach (string errPar in err.ErrorParameters) 
        {
            if (String.Empty != errPar) bld.Append("\n Err. Par. : " + errPar);
        }

    }
    MessageBox.Show(bld.ToString());
    bld.Remove(0, bld.Length);
}

...and see that my backwhacks should be regular whacks.

If that would have fixed it, I would have waxed poetic about my whacks pathetic, but I still get an err:

enter image description here

I run this code immediately on starting the app, so I wouldn't expect it to be used elsewhere already, but I guess the real question is, how can I prevent it/work around it?

UPDATE 7

The slanting of the whacks apparently have nothing to do with it; I changed the connection string from forward whacks to the original back whacks and get the same exact err dialog.

UPDATE 8

Another oddity is, though, that if I use backwhacks instead of forward whacks in the Connection String, it actually does change the err msg a little:

enter image description here

(with backwhacks, the "Err. Par." path to the database does not appear in the err msg). As the examples I see show a backwhack, I'll assume that is the canonical/right way to do it, though...

UPDATE 9

When I, based on what I read here, added "File Mode=Read Write;" to my connection string so that it is:

@"Data Source=\My Documents\HHSDB003.sdf; File Mode=Read Write;");

...it gets worse in the sense that now it won't even show me the "80004005 There is a file sharing violation. A different process might be using the file." err msg any more. It instead gets cryptic and teases:

enter image description here

Community
  • 1
  • 1
B. Clay Shannon
  • 1,055
  • 124
  • 399
  • 759
  • 2
    Are you sure `Open()` throws NRE? Documentation [says](http://msdn.microsoft.com/en-us/library/system.data.sqlserverce.sqlceconnection.open.aspx); it doesn't. Also [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Soner Gönül Oct 01 '14 at 16:05
  • 4
    Include the stacktrace in your question. – Daniel Kelley Oct 01 '14 at 16:06
  • @SonerGönül: I see the debug string before the call to Open(), and I don't see the one after the call, so it seems the call to Open() is problematic... – B. Clay Shannon Oct 01 '14 at 16:09
  • 2
    The problem seems to be in the string of connessione..fai a small demo program which performs only open and close connection to isolate the problem correctly – daniele3004 Oct 01 '14 at 16:10
  • 1
    Side note: "\My Documents\HHSDB003.SDF" may not be valid file path... Not likely the reason for NRE, but suspicious. – Alexei Levenkov Oct 01 '14 at 16:16
  • @AlexeiLevenkov: See the Update. – B. Clay Shannon Oct 01 '14 at 16:21
  • 1
    You're not checking all objects in the handler against null, and that's probably the NRE source. What does just a plain old MessageBox.Show(ee.ToString()) give you? – ctacke Oct 01 '14 at 22:36
  • I wish I could tell you; I'm getting, "Cannot copy HHS.exe The device has either stopped responding or has been disconnected" when trying to copy a new version of the .exe onto the handheld - even after a warm boot. – B. Clay Shannon Oct 01 '14 at 23:08

1 Answers1

1

The call to Open() isn't the problem, I don't think.

  • Your Open() statement is throwing an exception (probably because of invalid path or password or something).
  • It's caught by the catch statement.
  • The catch statement tries to show a Message box, injecting the InnerException as a string into the message.
  • The Exception has no InnerException, and returns null.
  • ToString() is called on null.
  • Null pointer exception leaks out.

A stack trace would clear this up in 10 seconds.

Clever Neologism
  • 1,274
  • 8
  • 9
  • I don't know how to get a Stack Trace on/from the handheld device where the .exe runs (can't run it from the PC; have to copy over the .exe to the device). – B. Clay Shannon Oct 01 '14 at 16:24
  • StackTrace is a string property of the Exception class. You are using a MessageBox to tell the user something in your catch... I think you can figure it out from there. – Clever Neologism Oct 01 '14 at 16:29
  • I'll try it, but I'm not too optimistic; after all, my "inner ex is" from my catch block never displays; why would the stack trace display? And I see no StackTrace available, anyway (see Update 2). – B. Clay Shannon Oct 01 '14 at 17:06
  • Don't trust Intellisense, look at the API. *Every* exception has a StackTrace property. As to why the stack trace would display while the InnerException doesn't, it's because it is that MessageBox.Show call that's actually failing... you are running into the exception while trying to print the InnerException. – Clever Neologism Oct 01 '14 at 17:21
  • With StackTrace, I get, "'System.Exception' does not contain a definition for 'StackTrace'"; see Update 3. – B. Clay Shannon Oct 01 '14 at 17:55
  • 1
    Well, you've solved the issue. It was exactly as I said... InnerException is null (based on your updates). Forget the StackTrace. You have discovered the null pointer exception source. "If there is an exception (and there is, because I reach the catch block), why is InnerException null?" Well, because there isn't one! InnerException is used when you use an exception to wrap another exception (Decorator Pattern). No message in Exception, so you only have the exception's type to go on I guess. – Clever Neologism Oct 01 '14 at 20:36
  • StackTrace *doesn't* exist in every Exception. This post is clearly tagged `compact-framework` and StackTrace doesn't exist in the Compact Framework. – ctacke Oct 01 '14 at 22:33
  • It does if you aren't using version 1. Version 2 was released in 2005... or 10 years ago. I'm not all-knowing ;). – Clever Neologism Oct 02 '14 at 15:10