Returning a mozIStorageConnection from an XPCOM component results in NS_ERROR_FAILURE

RESOLVED INVALID

Status

()

--
major
RESOLVED INVALID
10 years ago
10 years ago

People

(Reporter: jason.barnabe, Unassigned)

Tracking

({regression})

1.9.1 Branch
x86
Linux
regression
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

3.03 KB, application/x-xpinstall
Details
(Reporter)

Description

10 years ago
Created attachment 363793 [details]
test extension

I have a JavaScript XPCOM component that has a function that returns a mozIStorageConnection. In Firefox 3.0, it works fine. In Firefox 3.1b2, it gives NS_ERROR_FAILURE on the code that calls my connection.

1. Install the attached XPI in Firefox 3 and restart Firefox.
2. Go to chrome://connectiontest/content/test.xul

Result: You get an alert "Connection is [xpconnect wrapped mozIStorageConnection]"

1. Install the attached XPI in Firefox 3.1b2 and restart Firefox.
2. Go to chrome://connectiontest/content/test.xul

Result: You get an alert "Failed - [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [returningDataSource.getConnection]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: chrome://connectiontest/content/test.js :: <TOP_LEVEL> :: line 2"  data: no]"

Note that the object is created successfully in both cases (it logs to the error console before returning), it's the return from the XPCOM component that fails. If I replace the call to the XPCOM component with the code in the XPCOM component itself, things work fine. I've also tried a version of the same component that returns an nsIFile, and that's fine.
Are you saying the db connection is created just fine in both cases, but it just doesn't return from your component in 1.9.2?
(Reporter)

Comment 2

10 years ago
Yes, that's exactly what I'm saying.
This sounds like it deals more with xpconnect instead of storage - mrbkap?
This is invalid. The problem is that the IID for mozIStorageConnection in the .xpt file in the given extension is incorrect (623f9ddb-434b-4d39-bc2d-1c617da241d0). Since it was generated, the IID changed to (ac3c486c-69a1-4cbe-8f25-2ad20880eab3). Since you're trying to return a mozIStorageConnection from your function, when XPConnect tries to return it, it can't find the interface information (because the IID is wrong) and dies trying to wrap the unknown object.

Also, you have a typo in your nsIClassInfo.getInterfaces implementation: Components.interfaces.returningDatasource should be Components.interfaces.returningDataSource. In your given testcase this is an invisible error, because the returned object is explicitly QI'd to returningDataSource. I only found it because a debug build asserted (via NS_ASSERTION) about it.
Status: NEW → RESOLVED
Last Resolved: 10 years ago
Resolution: --- → INVALID
(Reporter)

Comment 5

10 years ago
Does that mean that if I regenerated the xpt based on Firefox 3.1 beta files, my new xpt would not work in Firefox 3.0?
(In reply to comment #5)
> Does that mean that if I regenerated the xpt based on Firefox 3.1 beta files,
> my new xpt would not work in Firefox 3.0?

Unfortunately yes. This is a really sad situation. jst and I were talking about some strategies to make things better. In particular, for JS components, we could lazily bind names to IIDs (and throw out the ones in the xpt files). At the very least, we should give a better warning. The only way I figured out what was going on here was a very cryptic NS_WARNING (so, debug only, "WARNING: Declared InterfaceInfo not found") and tracked down which interface it was that wasn't found.

What else can we do here (both short and long term) to make this suck less?
Why does a JS component even need an xpt?
Sorry, should have mentioned -- the extension in question defines an interface:

interface myIFoo : nsIClassInfo {
  mozIStorageConnection getConnection();
}

thus the xpt file that can become outdated.

(another workaround would be to return nsISupports and QI in the client code.)
This is going to bite anyone shipping xpt files that mention interfaces whose IIDs have been revved, right? The type of component they're shipping is immaterial, except that JS components tend to just work because they don't need binary compat usually.

Comment 10

10 years ago
The IDL file in question probably does

#include "mozIStorageConnection.idl"

Remove that line and instead do:

interface mozIStorageConnection

This means that the IID of mozIStorageConnection will not be recorded.
(Reporter)

Comment 11

10 years ago
Yes, that works, thank you. I didn't know you could do that.
You need to log in before you can comment on or make changes to this bug.