realm / realm-dart

Realm is a mobile database: a replacement for SQLite & ORMs.
Apache License 2.0
756 stars 84 forks source link

Intermittent error: Could not resolve annotation for `class $Test`. #1611

Open derrickgw opened 5 months ago

derrickgw commented 5 months ago

What happened?

Every so often, the build generator throws an error on the Annotation. I estimate this happens 1 out of 10 times.

I have also noticed that when it happens the build running tries to execute a few thousand steps instead of a few hundred. When it is in this state, rerunning it doesn't fix it. I have to modify the file (usually I add an extra newline) for it to run correctly.

Repro steps

Run the buildrunner. Every so often it will crash on the first insatnce of @RealmObject() in the file.

Version

Dart 3.2.6/Flutter 3.16.9

What type of application is this?

Flutter Application

Client OS and version

Ubuntu 20.04.4 LTS

Code snippets

import 'package:const_date_time/const_date_time.dart';
import 'package:dart_numerics/dart_numerics.dart' as numerics;

import 'package:flutter/material.dart';

import 'package:realm/realm.dart';

import '../process_pictures.dart';
export 'package:realm/realm.dart' show ObjectId;

part 'picture.realm.dart';

const int myconst = 1;
@RealmModel()
class $Test {
  @PrimaryKey()
  ObjectId id = ObjectId();
  int value1 = myconst;
  int value2 = numerics.int64MinValue;
}

Stacktrace of the exception/crash you're getting

#0      TypeChecker._computeConstantValue (package:source_gen/src/type_checker.dart:114:7)
#1      TypeChecker._annotationsWhere (package:source_gen/src/type_checker.dart:139:21)
#2      _SyncStarIterator.moveNext (dart:async-patch/async_patch.dart:558:14)
#3      SetBase.addAll (dart:collection/set.dart:58:23)
#4      _Set.addAll (dart:collection-patch/compact_hash.dart:986:11)
#5      new LinkedHashSet.of (dart:collection/linked_hash_set.dart:192:27)
#6      Iterable.toSet (dart:core/iterable.dart:512:21)
#7      ElementEx._annotationsInfoOfExact (package:realm_generator/src/element.dart:62:53)
#8      _SyncStarIterator.moveNext (dart:async-patch/async_patch.dart:558:14)
#9      new _GrowableList._ofOther (dart:core-patch/growable_array.dart:202:26)
#10     new _GrowableList.of (dart:core-patch/growable_array.dart:152:26)
#11     new List.of (dart:core-patch/array_patch.dart:39:18)
#12     Iterable.toList (dart:core/iterable.dart:497:7)
#13     ElementEx.annotationInfoOfExact (package:realm_generator/src/element.dart:73:58)
#14     ClassElementEx.realmModelInfo (package:realm_generator/src/class_element_ex.dart:50:42)
#15     ClassElementEx.realmInfo (package:realm_generator/src/class_element_ex.dart:54:25)
#16     _extension#0.realmInfo.<anonymous closure> (package:realm_generator/src/realm_object_generator.dart:63:58)
#17     MappedIterator.moveNext (dart:_internal/iterable.dart:403:20)
#18     WhereIterator.moveNext (dart:_internal/iterable.dart:450:22)
#19     CastIterator.moveNext (dart:_internal/cast.dart:61:30)
#20     ExpandIterator.moveNext (dart:_internal/iterable.dart:489:21)
#21     new _GrowableList._ofOther (dart:core-patch/growable_array.dart:202:26)
#22     new _GrowableList.of (dart:core-patch/growable_array.dart:152:26)
#23     new List.of (dart:core-patch/array_patch.dart:39:18)
#24     Iterable.toList (dart:core/iterable.dart:497:7)
#25     RealmObjectGenerator.generate.<anonymous closure>.<anonymous closure> (package:realm_generator/src/realm_object_generator.dart:48:84)
#26     _rootRun (dart:async/zone.dart:1399:13)
#27     _CustomZone.run (dart:async/zone.dart:1301:19)
#28     _runZoned (dart:async/zone.dart:1804:10)
#29     runZonedGuarded (dart:async/zone.dart:1792:12)
#30     scopeSession (package:realm_generator/src/session.dart:29:16)
#31     RealmObjectGenerator.generate.<anonymous closure> (package:realm_generator/src/realm_object_generator.dart:45:16)
<asynchronous suspension>
#32     measure.<anonymous closure> (package:realm_generator/src/measure.dart:36:18)
<asynchronous suspension>
#33     measure (package:realm_generator/src/measure.dart:33:7)
<asynchronous suspension>
#34     RealmObjectGenerator.generate (package:realm_generator/src/realm_object_generator.dart:41:12)
<asynchronous suspension>
#35     _generate (package:source_gen/src/builder.dart:342:23)
<asynchronous suspension>
#36     Stream.toList.<anonymous closure> (dart:async/stream.dart:1351:9)
<asynchronous suspension>

Relevant log output

$  dart run build_runner build --verbose
[INFO] Entrypoint:Generating build script...
[INFO] Entrypoint:Generating build script completed, took 368ms

[INFO] BuildDefinition:Initializing inputs
[INFO] BuildDefinition:Reading cached asset graph...
[INFO] BuildDefinition:Reading cached asset graph completed, took 416ms

[INFO] BuildDefinition:Checking for updates since last build...
[INFO] BuildDefinition:Checking for updates since last build completed, took 1.9s

[INFO] Build:Running build...
[INFO] Build:Running build completed, took 49ms

[INFO] Build:Caching finalized dependency graph...
[INFO] Build:Caching finalized dependency graph completed, took 200ms

[SEVERE] realm:realm_generator on lib/model/data/picture.dart (cached):

line 1, column 333 of package:sustain/model/data/picture.dart: Could not resolve annotation for `class $Test`.
  ╷
1 │ @RealmModel()
  │ ^^^^^^^^^^^^^
  ╵
#0      TypeChecker._computeConstantValue (package:source_gen/src/type_checker.dart:114:7)
#1      TypeChecker._annotationsWhere (package:source_gen/src/type_checker.dart:139:21)
#2      _SyncStarIterator.moveNext (dart:async-patch/async_patch.dart:558:14)
#3      SetBase.addAll (dart:collection/set.dart:58:23)
#4      _Set.addAll (dart:collection-patch/compact_hash.dart:986:11)
#5      new LinkedHashSet.of (dart:collection/linked_hash_set.dart:192:27)
#6      Iterable.toSet (dart:core/iterable.dart:512:21)
#7      ElementEx._annotationsInfoOfExact (package:realm_generator/src/element.dart:62:53)
#8      _SyncStarIterator.moveNext (dart:async-patch/async_patch.dart:558:14)
#9      new _GrowableList._ofOther (dart:core-patch/growable_array.dart:202:26)
#10     new _GrowableList.of (dart:core-patch/growable_array.dart:152:26)
#11     new List.of (dart:core-patch/array_patch.dart:39:18)
#12     Iterable.toList (dart:core/iterable.dart:497:7)
#13     ElementEx.annotationInfoOfExact (package:realm_generator/src/element.dart:73:58)
#14     ClassElementEx.realmModelInfo (package:realm_generator/src/class_element_ex.dart:50:42)
#15     ClassElementEx.realmInfo (package:realm_generator/src/class_element_ex.dart:54:25)
#16     _extension#0.realmInfo.<anonymous closure> (package:realm_generator/src/realm_object_generator.dart:63:58)
#17     MappedIterator.moveNext (dart:_internal/iterable.dart:403:20)
#18     WhereIterator.moveNext (dart:_internal/iterable.dart:450:22)
#19     CastIterator.moveNext (dart:_internal/cast.dart:61:30)
#20     ExpandIterator.moveNext (dart:_internal/iterable.dart:489:21)
#21     new _GrowableList._ofOther (dart:core-patch/growable_array.dart:202:26)
#22     new _GrowableList.of (dart:core-patch/growable_array.dart:152:26)
#23     new List.of (dart:core-patch/array_patch.dart:39:18)
#24     Iterable.toList (dart:core/iterable.dart:497:7)
#25     RealmObjectGenerator.generate.<anonymous closure>.<anonymous closure> (package:realm_generator/src/realm_object_generator.dart:48:84)
#26     _rootRun (dart:async/zone.dart:1399:13)
#27     _CustomZone.run (dart:async/zone.dart:1301:19)
#28     _runZoned (dart:async/zone.dart:1804:10)
#29     runZonedGuarded (dart:async/zone.dart:1792:12)
#30     scopeSession (package:realm_generator/src/session.dart:29:16)
#31     RealmObjectGenerator.generate.<anonymous closure> (package:realm_generator/src/realm_object_generator.dart:45:16)
<asynchronous suspension>
#32     measure.<anonymous closure> (package:realm_generator/src/measure.dart:36:18)
<asynchronous suspension>
#33     measure (package:realm_generator/src/measure.dart:33:7)
<asynchronous suspension>
#34     RealmObjectGenerator.generate (package:realm_generator/src/realm_object_generator.dart:41:12)
<asynchronous suspension>
#35     _generate (package:source_gen/src/builder.dart:342:23)
<asynchronous suspension>
#36     Stream.toList.<anonymous closure> (dart:async/stream.dart:1351:9)
<asynchronous suspension>

in: package:sustain/model/data/picture.dart:15:7
   ╷
14 │ @RealmModel()
15 │ class $Test {
   │       ^^^^^
   ╵
Unexpected error. Please open an issue on: https://github.com/realm/realm-dart

package:realm_generator/src/class_element_ex.dart 210:7        ClassElementEx.realmInfo
package:realm_generator/src/realm_object_generator.dart 63:58  _extension#0.realmInfo.<fn>
dart:core                                                      Iterable.toList
package:realm_generator/src/realm_object_generator.dart 48:84  RealmObjectGenerator.generate.<fn>.<fn>
dart:async                                                     runZonedGuarded
package:realm_generator/src/session.dart 29:16                 scopeSession
package:realm_generator/src/realm_object_generator.dart 45:16  RealmObjectGenerator.generate.<fn>
package:realm_generator/src/measure.dart 36:18                 measure.<fn>
package:realm_generator/src/measure.dart 33:7                  measure
package:realm_generator/src/realm_object_generator.dart 41:12  RealmObjectGenerator.generate
package:source_gen/src/builder.dart 342:23                     _generate

[SEVERE] Build:
Failed after 281ms
sync-by-unito[bot] commented 5 months ago

➤ PM Bot commented:

Jira ticket: RDART-994

jankuo commented 5 months ago

you must rename $Test to _Test.

Model class must start with _

nielsenko commented 5 months ago

@jankuo and @derrickgw You can name the model $Test. Actually it is needed for cross-file links.

@derrickgw Is the above short snippet enough to reproduce the issue for you? What version of realm are you using?

As a workaround, can you try to delete the .dart_tool folder, and try again?

derrickgw commented 5 months ago

@jankuo I was also surprised that $Test was legal.

@nielsenko I have seen the error even with this small example. I am sure that deleting .dart_tool folder would work. Simply changing the file and running build_runner again will clear the error. I have seen the error with both 1.6 and 2.0.

I recognize that it is hard to track down intermittent errors like this. Is there any sort of extra debugging or logging I can turn on to get more information?

nielsenko commented 5 months ago

@derrickgw I believe it is an issue with the analyzer package, or our use of it. If you check your pubspec.lock what version of the analyzer are you currently using?

derrickgw commented 5 months ago

I don't rely directly on analyzer. It looks like I am using 6.2. I can try explicitly referencing it and upgrading to 6.4 to see if that has an impact.

derrickgw commented 5 months ago

I upgraded flutter and analyzer to the latest, and was still able to get the error:

deleting .dart_tool almost makes it happen reliably on the 2nd build. I wrote a test script and attached the output.

#!/bin/sh -x
rm -r  .dart_tool/

for ii in $(seq 1 4); do
    echo $ii
    date
    echo >> lib/model.dart
    dart run build_runner build --delete-conflicting-outputs -v || dart run build_runner build --delete-conflicting-outputs -v

    date
    head -n -1 lib/model.dart > model.dart; mv model.dart lib/model.dart;
    dart run build_runner build --delete-conflicting-outputs -v || dart run build_runner build --delete-conflicting-outputs -v

done;

test_output.log

nielsenko commented 5 months ago

@derrickgw Thanks! I'll try to reproduce on my end.

nielsenko commented 5 months ago

@derrickgw I managed to hit the issue. Now I "just" need to figure out why.

realth000 commented 4 months ago

This issue also occurs with the latest realm 2.0 / flutter 3.19.5.

There is a workaround, in the source file that defines the schema, import realm_common (direct package contains the annotation) , like this:

import 'package:realm/realm.dart';
+++ import 'package:realm_common/realm_common.dart';

Second build runs well after this change, no more dart run build_runner clean required.

Don't forget flutter pub add -d realm_common to add realm_common as dev dependency.

realth000 commented 4 months ago

Maybe dart codegen does not support indirect package import when caching?

Riverpod also has a separate package riverpod_annotation but I didn't find info related to build error in the commit history.

Riverpod requires adding riverpod_annotation as dependency in doc Get Started

APPXOTICA commented 3 months ago

This issue also occurs with the latest realm 2.0 / flutter 3.19.5.

There is a workaround, in the source file that defines the schema, import realm_common (direct package contains the annotation) , like this:

import 'package:realm/realm.dart';
+++ import 'package:realm_common/realm_common.dart';

Second build runs well after this change, no more dart run build_runner clean required.

Don't forget flutter pub add -d realm_common to add realm_common as dev dependency.

realm: ^2.3.0 has same issue and this solution worked.