Closed
Bug 1064506
Opened 11 years ago
Closed 11 years ago
Eradicate redundant null checks from BrowserDB
Categories
(Firefox for Android Graveyard :: Data Providers, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
Firefox 35
People
(Reporter: ckitching, Assigned: ckitching)
Details
Attachments
(1 file)
|
16.75 KB,
patch
|
rnewman
:
review+
|
Details | Diff | Splinter Review |
Richard pointed out in another bug the following antipattern:
Foo x;
try {
x = bar();
} finally {
if (x != null) {
x.close();
}
}
Unfortunately, BrowserDB is full of it. Lots of it is my fault. Let's fix that.
| Assignee | ||
Updated•11 years ago
|
Component: Overlays → General
| Assignee | ||
Comment 1•11 years ago
|
||
Attachment #8485960 -
Flags: review?(rnewman)
| Assignee | ||
Comment 2•11 years ago
|
||
Updated•11 years ago
|
Status: NEW → ASSIGNED
Component: General → Data Providers
Hardware: ARM → All
Comment 3•11 years ago
|
||
Comment on attachment 8485960 [details] [diff] [review]
Eradicate lazy cursor pattern
Review of attachment 8485960 [details] [diff] [review]:
-----------------------------------------------------------------
::: mobile/android/base/db/LocalBrowserDB.java
@@ +540,5 @@
> uri = mFaviconsUriWithProfile;
> columns = new String[] { Favicons._ID };
> }
> if (uri != null) {
> + Cursor cursor = cr.query(uri, columns, constraint, null, null);
final
@@ +735,3 @@
>
> + // Check to see if there are any bookmarks in one of our three
> + // fixed "Desktop Boomarks" folders.
Bookmarks
@@ +735,4 @@
>
> + // Check to see if there are any bookmarks in one of our three
> + // fixed "Desktop Boomarks" folders.
> + Cursor c = cr.query(bookmarksUriWithLimit(1),
final
@@ +739,3 @@
> new String[] { Bookmarks._ID },
> Bookmarks.PARENT + " = ? OR " +
> Bookmarks.PARENT + " = ? OR " +
Correct indentation in this block.
@@ +755,5 @@
> }
>
> @RobocopTarget
> public boolean isBookmark(ContentResolver cr, String uri) {
> + Cursor c = cr.query(bookmarksUriWithLimit(1),
final
@@ +758,5 @@
> public boolean isBookmark(ContentResolver cr, String uri) {
> + Cursor c = cr.query(bookmarksUriWithLimit(1),
> + new String[] { Bookmarks._ID },
> + Bookmarks.URL + " = ? AND " +
> + Bookmarks.PARENT + " != ?",
Correct indenting.
@@ +761,5 @@
> + Bookmarks.URL + " = ? AND " +
> + Bookmarks.PARENT + " != ?",
> + new String[] { uri,
> + String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID) },
> + Bookmarks.URL);
Same.
@@ +777,4 @@
> }
>
> public boolean isReadingListItem(ContentResolver cr, String uri) {
> + Cursor c = cr.query(mReadingListUriWithProfile,
final
@@ +822,5 @@
> }
> }
>
> public String getUrlForKeyword(ContentResolver cr, String keyword) {
> + Cursor c = cr.query(mBookmarksUriWithProfile,
final (might fix the indenting, too!)
@@ +837,3 @@
> }
>
> return null;
Move this inside the `try`, early return null if !c.moveToFirst.
@@ +888,5 @@
> values.put(Bookmarks.PARENT, folderId);
> values.put(Bookmarks.DATE_MODIFIED, now);
>
> // Get the page's favicon ID from the history table
> + Cursor c = cr.query(mHistoryUriWithProfile,
final.
@@ +1002,5 @@
> * @param faviconURL The URL of the favicon to fetch from the database.
> * @return The decoded Bitmap from the database, if any. null if none is stored.
> */
> public LoadFaviconResult getFaviconForUrl(ContentResolver cr, String faviconURL) {
> + Cursor c = cr.query(mFaviconsUriWithProfile,
final
@@ +1028,5 @@
> return FaviconDecoder.decodeFavicon(b);
> }
>
> public String getFaviconUrlForHistoryUrl(ContentResolver cr, String uri) {
> + Cursor c = cr.query(mHistoryUriWithProfile,
final
@@ +1044,3 @@
> }
>
> return null;
Same comment as above.
@@ +1095,5 @@
> }
>
> @RobocopTarget
> public byte[] getThumbnailForUrl(ContentResolver cr, String uri) {
> + Cursor c = cr.query(mThumbnailsUriWithProfile,
final
@@ +1162,5 @@
> + };
> +
> +
> + // We need to get the old visit count.
> + Cursor cursor = cr.query(getAllHistoryUri(),
final
::: mobile/android/base/moz.build
@@ +15,5 @@
> ajar.sources = [
> 'annotations/generatorannotations/OptionalGeneratedParameter.java',
> 'annotations/generatorannotations/WrapElementForJNI.java',
> 'annotations/generatorannotations/WrapEntireClassForJNI.java',
> + 'annotations/JNITarget.java',
Looks like this should be in a different patch.
Attachment #8485960 -
Flags: review?(rnewman) → review+
| Assignee | ||
Comment 4•11 years ago
|
||
Comment 5•11 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 35
Comment 6•11 years ago
|
||
I stumbled upon an exception during a test run that looks like an NPE is being fired from the | finally | block because the cursor is null. Comment 0 doesn't give enough context to know why this is an anti-pattern:
W/dalvikvm( 4051): threadid=29: thread exiting with uncaught exception (group=0x40b741f8)
E/GeckoAppShell( 4051): >>> REPORTING UNCAUGHT EXCEPTION FROM THREAD 164 ("ModernAsyncTask #3")
E/GeckoAppShell( 4051): java.lang.NullPointerException
E/GeckoAppShell( 4051): at org.mozilla.gecko.db.LocalBrowserDB.desktopBookmarksExist(LocalBrowserDB.java:755)
E/GeckoAppShell( 4051): at org.mozilla.gecko.db.LocalBrowserDB.getBookmarksInFolder(LocalBrowserDB.java:681)
E/GeckoAppShell( 4051): at org.mozilla.gecko.db.BrowserDB.getBookmarksInFolder(BrowserDB.java:156)
E/GeckoAppShell( 4051): at org.mozilla.gecko.home.BookmarksPanel$BookmarksLoader.loadCursor(BookmarksPanel.java:196)
E/GeckoAppShell( 4051): at org.mozilla.gecko.home.SimpleCursorLoader.loadInBackground(SimpleCursorLoader.java:44)
E/GeckoAppShell( 4051): at org.mozilla.gecko.home.SimpleCursorLoader.loadInBackground(SimpleCursorLoader.java:26)
E/GeckoAppShell( 4051): at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:242)
E/GeckoAppShell( 4051): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
E/GeckoAppShell( 4051): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
E/GeckoAppShell( 4051): at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
E/GeckoAppShell( 4051): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
E/GeckoAppShell( 4051): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/GeckoAppShell( 4051): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
E/GeckoAppShell( 4051): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
E/GeckoAppShell( 4051): at java.lang.Thread.run(Thread.java:856)
Full log:
https://tbpl.mozilla.org/php/getParsedLog.php?id=48815950&tree=Try&full=1
Comment 7•11 years ago
|
||
(In reply to Mark Finkle (:mfinkle) from comment #6)
> I stumbled upon an exception during a test run that looks like an NPE is
> being fired from the | finally | block because the cursor is null. Comment 0
> doesn't give enough context to know why this is an anti-pattern:
It's an anti-pattern because:
1. The only time you should get a null instead of a cursor is if you have a syntax error in your query string. That's not something we want to muffle.
2. Usually the pattern looks like this:
Cursor c = null;
try {
c = cr.query(...);
c.moveToFirst();
...
} finally {
if (c != null) {
c.close();
}
}
which will result in a NPE regardless of that finally clause!
If you're going to null check in this scenario, this is how to do it correctly:
Cursor c = cr.query(...);
if (c == null) {
Log.e(LOGTAG, "Oh no!");
return 0;
}
try {
c.moveToFirst();
...
} finally {
c.close();
}
Updated•5 years ago
|
Product: Firefox for Android → Firefox for Android Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•