Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

500 database error (error opening!: 23) when saving a new document in app pause state #1405

Closed
HanzhiDou opened this issue Aug 17, 2016 · 11 comments

Comments

@HanzhiDou
Copy link

HanzhiDou commented Aug 17, 2016

Hi,

  • Version: 1.2.1 by Couchbase Lite Phonegap plugin
  • Client OS: ios 9.3 (it happens also in earlier versions)

My ios cordova app uses the couchbase lite phonegap plugin, sometimes it can not save documents in app pause state(app is running in background), the restful save request get error response as below:

{ ... "status":500,"statusText":"Internal Server Error","responseText":"{\"status\":500,\"error\":\"Database error!\"}","responseXML":null,"responseBytes":null}

There is also one log:

error opening!: 23

However the save operation can succeed once app resumes from background mode, so just some documents are lost from user point of view. After further investigation and many tests, I observed the error occurred only when:

  • app in background mode
  • the database has never been read before the save document operation

Workaround: I add one query view operation just after the database ready in app startup phase, the error disappeared.

Though the workaround works, it's better to find the root cause and fix it.

Thanks!

@snej
Copy link
Contributor

snej commented Aug 17, 2016

Are there any warnings written to the app's console log?

Can you explain how the app is running while in the background? Did you use a system API to get background time or to handle a notification?

The problem may be with the iOS file protection options — the default for CBL databases is NSFileProtectionCompleteUnlessOpen, which means that files can't be opened while the device is locked. This won't affect the main database file, which remains open, but would cause trouble for reading attachments, for example.

@HanzhiDou
Copy link
Author

The error in console log:
error opening!: 23
The app uses background location updates, once new location available, it save the info to cbl.

background task is used to make the app running in background (beginBackgroundTaskWithExpirationHandler).

There is no attachment in this database, and the save operation is happened only after cbl ready and location updates are manual started.

@snej
Copy link
Contributor

snej commented Sep 14, 2016

We don't have a REST API for changing the file protection settings of the database files. I think we'd need to add one, for this case. Then you can use a more lenient setting that allows you to access files while in the background.

@snej
Copy link
Contributor

snej commented Sep 14, 2016

Note: We'd implement this along with the other proposed REST API extension to specify the db storage type, encryption key, etc.

@snej snej added the P1: high label Sep 14, 2016
@npomfret
Copy link

npomfret commented Sep 27, 2016

I'm also seeing thousands of these messages in the log

<Notice>: error opening!: 23

Is there a workaround?

@snej
Copy link
Contributor

snej commented Sep 27, 2016

On Sep 27, 2016, at 1:47 AM, Nick Pomfret [email protected] wrote:

I'm also seeing thousands of these messages in the log

: error opening!: 23

Is there a workaround?

Yes, but it’s not available to PhoneGap apps unless you modify the native plugin code. You need to change the file protection mode of the CBLManager to one of the modes that allows file access after the app has been backgrounded. (Sorry, I don’t have the long names of those enums memorized!) We’re aware that this should be accessible from the REST API and have an issue open on that.

(It appears that iOS 10 is quicker to make files inaccessible after an app backgrounds; this problem has been coming up a lot more often.)

—Jens

@npomfret
Copy link

npomfret commented Sep 28, 2016

I'm using react-native so have access to the native code. I'll see what I can get working. Thanks for the advice. Can you point me at some docs?

@npomfret
Copy link

Does NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication sound familiar?

I'm scratching around a bit here. My code was doing this:

CBLManager* dbmgr = [CBLManager sharedInstance]

And I've tried changing to this:

        NSString* dir = [CBLManager defaultDirectory];
        CBLManagerOptions options = {};
        options.fileProtection = NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication;
        NSError* error;
        CBLManager* dbmgr =   [[CBLManager alloc] initWithDirectory: dir options: &options error: &error];

But its not worked. My databases aren't accessible over the rest api.

@snej
Copy link
Contributor

snej commented Sep 28, 2016

dbmgr has to remain valid for the lifetime of the app, so you should make it a global variable, or an instance variable of the app delegate. Otherwise the reference will be released as soon as that method exits, which I believe will cause the manager to be dealloced. (Ah, the joys of using a language without full garbage collection!)

@npomfret
Copy link

npomfret commented Sep 28, 2016

Thank you! It's not live yet, but I hope this will improve the application responsiveness when backgrounded for long periods of time. At the moment my push notifications and background fetch operations only work for a while and eventually stop.

In case anyone out there is as incompetent as me, here's the change I made:

Instead of [CBLManager sharedInstance]...

        CBLManagerOptions options = {NO, NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication};
        NSError* error;
        manager = [[CBLManager alloc] initWithDirectory: [CBLManager defaultDirectory]
                                                        options: &options error: &error];

And add this to my header file:

#import <CouchbaseLite/CouchbaseLite.h>

@interface ...
{
...
CBLManager *manager;
}
@end

I think owe you (and Jens) a beer!

@pasin
Copy link
Contributor

pasin commented Dec 16, 2016

I added couchbaselabs/Couchbase-Lite-PhoneGap-Plugin#89 for adding a configuration to set PhoneGap iOS file protection level. I will close this issue here.

@pasin pasin closed this as completed Dec 16, 2016
@pasin pasin removed the backlog label Dec 16, 2016
snej added a commit that referenced this issue Dec 16, 2016
* Enabled file protection in the iOS test app (note: only takes effect
  on a real device; simulator does not implement file protection!)
* The test app logs when app state changes in various ways, like going
  into/out of the background or files becoming inaccessible.
* Made MYBackgroundMonitor work better if the app is already backgrounded
  and if the background task expires. (See MYUtilities commit)
* Added CBLDatabase.fileProtection property
* REST replicator monitors when files become inaccessible and suspends
  the replicator for the duration.
* Thread-safety improvements in CBLRestReplicator+Backgrounding: make
  sure UIApplication is only called on the main thread.
* Defined new internal status kCBLStatusFilesystemLocked for when we
  know that file I/O failed due to file protection. It gets reported
  as a 500 status with message “Device locked”.

Should fix #1461 (background monitor); #1443 #1422 #1405 (file protection).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants