isar / isar/hive

HiveError thrown twice

Open
#1,255 1 comment 2 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
4.4k
Forks
449
PR merge metrics
No merged PRs in 30d

Description

In our flutter project we want to encrypt our Hive database, and we want to know in case of decryption error, so we deactivate `crashRecovery`, and expect to catch one `HiveError` in case of problem when opening a box.

But as weird as it can be, I think a single instance of `HiveError` is thrown twice... and only one is "catchable".

Please see the following code main function in a standard flutter project:

```dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Hive.init((await getApplicationDocumentsDirectory()).path);

Box? myBox;
try {
myBox = await Hive.openBox(
'my_box',
// New encryption key at each run: should result in exception at 2nd run
encryptionCipher: HiveAesCipher(Hive.generateSecureKey()),
// Deactivate crash recovery so that we can be informed of error
crashRecovery: false,
);
} catch (error) {
print('Caught error: $error');
}

// Just exercise hive
myBox?.add(42);

runApp(const MyApp());
}
```

At 2nd run of the app, an error is expected, but we get the following in the console:
```
I/flutter (29768): Caught error: HiveError: Wrong checksum in hive file. Box may be corrupted.
E/flutter (29768): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HiveError: Wrong checksum in hive file. Box may be corrupted.
E/flutter (29768): #0 StorageBackendVm.initialize (package:hive/src/backend/vm/storage_backend_vm.dart:98:9)
E/flutter (29768):
E/flutter (29768): #1 HiveImpl._openBox (package:hive/src/hive_impl.dart:111:9)
E/flutter (29768):
E/flutter (29768): #2 HiveImpl.openBox (package:hive/src/hive_impl.dart:142:12)
E/flutter (29768):
E/flutter (29768): #3 main (package:hive_demo/main.dart:11:13)
E/flutter (29768):
```

`catch` successfully caught one exception (see 1st line, this is expected), but another one seems to be uncaught (see lines 2-8, this is not expected).

And if removing the try-catch around the call to `Hive.openBox`, we get:
```
E/flutter (30486): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HiveError: Wrong checksum in hive file. Box may be corrupted.
E/flutter (30486): #0 StorageBackendVm.initialize (package:hive/src/backend/vm/storage_backend_vm.dart:98:9)
E/flutter (30486):
E/flutter (30486): #1 HiveImpl._openBox (package:hive/src/hive_impl.dart:111:9)
E/flutter (30486):
E/flutter (30486): #2 HiveImpl.openBox (package:hive/src/hive_impl.dart:142:12)
E/flutter (30486):
E/flutter (30486): #3 main (package:hive_demo/main.dart:11:11)
E/flutter (30486):
E/flutter (30486):
E/flutter (30486): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: HiveError: Wrong checksum in hive file. Box may be corrupted.
E/flutter (30486): #0 StorageBackendVm.initialize (package:hive/src/backend/vm/storage_backend_vm.dart:98:9)
E/flutter (30486):
E/flutter (30486): #1 HiveImpl._openBox (package:hive/src/hive_impl.dart:111:9)
E/flutter (30486):
E/flutter (30486): #2 HiveImpl.openBox (package:hive/src/hive_impl.dart:142:12)
E/flutter (30486):
E/flutter (30486): #3 main (package:hive_demo/main.dart:11:11)
E/flutter (30486):
E/flutter (30486):
```

Where it seems the exact same exception instance is uncaught twice 😬

The demo pubspec.yaml (with Flutter 3.13.8):
```
dependencies:
flutter:
sdk: flutter

hive: ^2.2.3
path_provider: ^2.1.1
```

We have investigated a bit the hive package code (v2.2.3) and we may have found the root cause in hive_impl.dart at line 116-123:
```
} catch (error, stackTrace) {
newBox?.close();
completer.completeError(error, stackTrace);
rethrow;
} finally {
// ignore: unawaited_futures
_openingBoxes.remove(name);
}
```

We think that the error is, here, kind of duplicated:

- once with `completeError` (we think this one is out of scope to be caught)
- another time with `rethrow` (this one is probably the one which is caught in main)

Thank you in advance for you help 😊

**Edit:**
Further insight, we have tried to comment `completer.completeError(error, stackTrace)` (hive_impl.dart:118) in our local checkout of hive package, and the uncaught exception/error has disappeared. Therefore, this is probably the root cause. But simply removing this line may break some functionality elsewhere (we have no experience in the hive code).

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the reproduction in the issue and inspect lib/hive_impl.dart around lines 116-123, especially completeError and rethrow. Trace how Hive.openBox and _openingBoxes use the completer, then verify that the fix reports the decryption error once without breaking box-opening behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.