How to programmatically trigger an InconsistentAnalysisException and how to retry the analysis after such an error?

59 views
Skip to first unread message

dark...@gmail.com

unread,
Feb 17, 2023, 10:14:42 PM2/17/23
to Dart Analyzer Discussion
Hello!

I'm fighting with InconsistentAnalysisExceptions. I understand broadly what these are about, but their abstract nature makes it difficult for me to fix them.

First, I'm not sure how to reliably trigger one. Is there a way to manually trigger such an exception, so that we can write tests for code-paths impacted by it?

Secondly, what is the correct way of obtaining a new valid analysis result? Naively I thought calling AnalysisContext.currentSession.getSomeResult again would do the trick. But apparently not.
Is there a special solution to deal with those?

Thanks!

Brian Wilkerson

unread,
Feb 20, 2023, 12:37:49 PM2/20/23
to analyzer...@dartlang.org
> Is there a way to manually trigger such an exception, so that we can write tests for code-paths impacted by it?

Yes.

An analysis context is a set of files that are all analyzed against the same set of package versions, using the same set of analysis options. An analysis session is the object used to request the analysis of some file within a single analysis context. The exception is triggered when a session is asked to analyze a file and the result of that analysis might be inconsistent with the state of the files in the context at the time the session was created. In that sense it's similar to a `ConcurrentModificationError`.

The easiest way to force the exception to be thrown is to modify the content of one of the files in the analysis context. We don't currently do any fine-grained analysis, so any change will work, but changing the public API of the file being modified will guard against future optimizations (assuming that the file being analyzed is, or depends on, the file being modified).

> Secondly, what is the correct way of obtaining a new valid analysis result? Naively I thought calling AnalysisContext.currentSession.getSomeResult again would do the trick. But apparently not.

That should generally work. I can only think of two cases where it wouldn't work
- if the session is modified again after `currentSession` returns but before the result could be computed (the computation of most results is async), or
- if the exception was caused by a need to rebuild the analysis contexts, in which case it seems likely that any sessions built by the old contexts would always throw the exception.

Not knowing why accessing the now current session isn't working makes it hard for me to suggest a more specific solution, but the general approach that I would recommend is the one that we follow in the analysis server, which is to drop back to the point at which we're handling a request and restart from the point where we find the analysis context based on the file path. Not doing so might allow for the possibility of using results computed from two different states of the file system, which could cause invalid results.

--
You received this message because you are subscribed to the Google Groups "Dart Analyzer Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to analyzer-discu...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/analyzer-discuss/2aea1442-f5bb-4c76-8bbb-95e7351d7436n%40dartlang.org.

dark...@gmail.com

unread,
Mar 9, 2023, 1:40:51 PM3/9/23
to Dart Analyzer Discussion, brianwilkerson
Hello again!

Thanks for the detailed answer and sorry for the slow reply.

Since my code is wrapped in a retry logic and using `currentSession`, I don't think the first cause of an InconsistentAnalysisException you mentioned is the problem.
It could be the second though as I'm reusing the AnalysisContext. But what causes an AnalysisContext to need to rebuild? A dependency change?


As for manually triggering the exception, I tried making a test relying on the `resolveFile` API + dart:io, but I couldn't get analyzer to throw. 
I can't find how to insert snippets here, so here's a gist of a dart test I wrote while playing around: https://gist.github.com/rrousselGit/3934429d638163c42a13a60115fd4366
I'm likely missing something though.

This test looks similar to the SDK tests around throwing an InconsistentAnalysisException I found (https://github.com/dart-lang/sdk/blob/919eb05b27970ce993677f326fddf8bb8d9cc024/pkg/analyzer/test/src/dart/analysis/session_test.dart#L201).
But it's not clear to me what's different about it

Any tip? Thanks!

Konstantin Shcheglov

unread,
Mar 9, 2023, 2:25:16 PM3/9/23
to analyzer...@dartlang.org, brianwilkerson

  Here is code that demonstrates the exception.

import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';

Future<void> main() async {
final resourceProvider = OverlayResourceProvider(
PhysicalResourceProvider.INSTANCE,
);

final testPackageRootPath = '/home/test';
final testPackageLibPath = '$testPackageRootPath/lib';
final testPath = '$testPackageLibPath/test.dart';
resourceProvider.setOverlay(
testPath,
content: '',
modificationStamp: -1,
);

final collection = AnalysisContextCollection(
resourceProvider: resourceProvider,
includedPaths: [
testPackageRootPath,
],
);

final analysisContext = collection.contextFor(testPath);
var analysisSession = analysisContext.currentSession;

// We did not tell the context about any changed files.
await analysisSession.getResolvedUnit(testPath);

// Tell (lie) the context that a file changed.
// This invalidates [analysisSession].
analysisContext.changeFile('$testPackageLibPath/a.dart');

// Uncomment to be able to get a valid session.
// await analysisContext.applyPendingFileChanges();
// analysisSession = analysisContext.currentSession;

// The session was invalidated, so this will throw.
await analysisSession.getResolvedUnit(testPath);
}



--
Konstantin Scheglov
Software Engineer
Google, Inc.

dark...@gmail.com

unread,
Mar 9, 2023, 2:45:15 PM3/9/23
to Dart Analyzer Discussion, sche...@google.com, brianwilkerson
Thanks a lot!
Reply all
Reply to author
Forward
0 new messages