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

dart analyze should gracefully handle analysis options formatting errors #55987

Closed
parlough opened this issue Jun 12, 2024 · 8 comments
Closed
Assignees
Labels
analyzer-analysis-options area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. area-dart-cli Use area-dart-cli for issues related to the 'dart' command like tool. dart-cli-analyze Issues related to the 'dart analyze' tool

Comments

@parlough
Copy link
Member

parlough commented Jun 12, 2024

If you run dart analyze when your analysis_options.yaml has a syntax error, such as the following:

include: package:lints/recommended.yaml
f

Then you receive an error that isn't user friendly and unnecessarily highlights/exposes potentially confusing analyzer internals. The process doesn't fully exit either, needing to be killed.

$ dart analyze .
Analyzing ....                          
Error from the analysis server: Internal error: Failed to handle request: analysis.setAnalysisRoots
OptionsFormatException: Could not find expected ':' for simple key., <_FileSpan: from <FileLocation: 40 unknown source:2:1> to <FileLocation: 40 unknown source:2:1> "">
#0      AnalysisOptionsProvider.getOptionsFromString (package:analyzer/src/analysis_options/analysis_options_provider.dart:93:7)
#1      AnalysisOptionsProvider.getOptionsFromSource (package:analyzer/src/analysis_options/analysis_options_provider.dart:65:23)
#2      AnalysisOptionsProvider.getOptionsFromFile (package:analyzer/src/analysis_options/analysis_options_provider.dart:56:12)
#3      ContextBuilderImpl._createOptionsMap (package:analyzer/src/dart/analysis/context_builder.dart:209:34)
#4      ContextBuilderImpl.createContext (package:analyzer/src/dart/analysis/context_builder.dart:135:15)
#5      new AnalysisContextCollectionImpl (package:analyzer/src/dart/analysis/analysis_context_collection.dart:108:36)
#6      ContextManagerImpl._createAnalysisContexts.performContextRebuildGuarded.performContextRebuild (package:analysis_server/src/context_manager.dart:549:40)
<asynchronous suspension>
#7      ContextManagerImpl._createAnalysisContexts.performContextRebuildGuarded (package:analysis_server/src/context_manager.dart:694:11)
<asynchronous suspension>
#8      _CancellingTaskQueue.queue.<anonymous closure> (package:analysis_server/src/context_manager.dart:978:15)
<asynchronous suspension>
#9      ContextManagerImpl.setRoots (package:analysis_server/src/context_manager.dart:364:5)
<asynchronous suspension>
#10     LegacyAnalysisServer.setAnalysisRoots (package:analysis_server/src/legacy_analysis_server.dart:790:9)
<asynchronous suspension>
#11     AnalysisSetAnalysisRootsHandler.handle (package:analysis_server/src/handler/legacy/analysis_set_analysis_roots.dart:45:7)
<asynchronous suspension>
#12     LegacyAnalysisServer.handleRequest.<anonymous closure>.<anonymous closure> (package:analysis_server/src/legacy_analysis_server.dart:575:11)
<asynchronous suspension>
#13     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:14)
<asynchronous suspension>
#14     LegacyAnalysisServer.handleRequest.<anonymous closure> (package:analysis_server/src/legacy_analysis_server.dart:556:7)
<asynchronous suspension>


null
[RequestError code: SERVER_ERROR, message: OptionsFormatException: Could not find expected ':' for simple key., <_FileSpan: from <FileLocation: 40 unknown source:2:1> to <FileLocation: 40 unknown source:2:1> "">]

Tested at 6c6b104

@lrhn
Copy link
Member

lrhn commented Jun 12, 2024

Should probably catch the error and report it (more) gracefully. Don't know if this should be handled in the dart executable or at the analyzer end, but printing null suggests it's the CLI end that doesn't handle server errors.

(If the YAML parser could be made to recover from errors, it might be possible to give more precise errors too, but that depends on the yaml package.)

@lrhn lrhn added area-dart-cli Use area-dart-cli for issues related to the 'dart' command like tool. dart-cli-analyze Issues related to the 'dart analyze' tool labels Jun 12, 2024
@parlough
Copy link
Member Author

parlough commented Jun 12, 2024

\cc @DanTup Since I think you recently added some handling for when the analysis server crashes.

@parlough parlough added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label Jun 14, 2024
@DanTup
Copy link
Collaborator

DanTup commented Jun 17, 2024

I think there are two behaviours here that may be questionable, but I don't know what the desired behaviour is for each (cc @bwilkerson).

  1. What should the server do with an invalid analysis_options? Currently it's throwing an unhandled exception while trying to set the analysis which is sent back to the client with a stack trace. This seems wrong to me, but I don't know if the error is considered fatal or not.. If so, it should probably report the error in a more friendly way, and if not, should it just continue to set up the analysis roots and analyze as if the invalid file (or parts of) didn't exist?

  2. If the server does return an unhandled error to dart analyze, how should it be presented? The original comment above suggests it should be more user friendly (presumably not be a raw exception/stack trace) but if this is an edge case and indicates a bug in the server, I wonder if this information is useful, because it results in a much better bug report than if it was not included. I think this might depend on the kind of exception.. For example the above code is OptionsFormatException which suggests we know the issue here is an invalid analysis_options.yaml and could provide a useful message without the full exception. But if it was something like a RangeError, I think the raw exception could be useful (in which case, maybe dart analyzes behaviour is fine here, and the server should handle exactly what's in the server error responses).

@bwilkerson
Copy link
Member

What should the server do with an invalid analysis_options? Currently it's throwing an unhandled exception while trying to set the analysis which is sent back to the client with a stack trace. This seems wrong to me ...

I agree. I don't think the server should be returning an exception in this case.

The general design of the server is to recover from errors as cleanly as possible, notifying the user of the error with enough information that the user can fix the problem.

I don't know what the limitations of the yaml package are in this case, but server should, to the best of its ability, create a diagnostic indicating the location and nature of the problem. If it gets back a partial view of the file then we ought to use as much of the file as we get and ignore the rest, and then proceed with analysis.

Ideally, the dart analyze tool would then look at the diagnostics that are returned, and, if there are diagnostics reported against either any analysis_options.yaml or pubspec.yaml files it should print

  1. a notice indicating that the rest of the analysis might not be correct because of those issues,
  2. the diagnostics that might invalidate the rest of the results,
  3. a header indicating that the questionable diagnostics follow
  4. the rest of the diagnostics (or notice that no other diagnostics were found if that's the case).

If the server does return an unhandled error to dart analyze, how should it be presented?

Given that this should only happen as a result of an internal bug that the server couldn't recover from, I think it's reasonable for the command-line tool to print out the message and stack trace, prefixed by a message explaining that this is an internal error and asking the user to report it.

@DanTup DanTup self-assigned this Jun 17, 2024
@DanTup
Copy link
Collaborator

DanTup commented Jun 17, 2024

It seems we already handle generating diagnostics for the case above, the issue is just that the server crashes before it gets there (during setting the roots). There are many places already handling these errors, but not path in the stack trace above.

I've started a change at https://dart-review.googlesource.com/c/sdk/+/371861 which:

  1. Changes the text for unhandled errors from

    Error from the analysis server: (error)
    to
    An unexpected error was encountered by the Analysis Server.
    Please file an issue at https://github.com/dart-lang/sdk/issues/new with the following details:
    (this text was copied from another place in dartdev that handles top=level errors)

  2. Handles the parse error by returning an empty map for the options (as other places already did)
  3. Adds a suffix to analysis_options parse errors:

    Parse errors in analysis_options.yaml may result in other incorrect diagnostics.

The result is that dart analyze with the above analysis_options.yaml looks like this:

image

I'm not sure if we want to just mash that text on to the end of the error like that though - it's not what was suggested above, but it does mean that it appears in the clients instead of only dart analyze (where the same problem exists). We can discuss this on the CL though.

copybara-service bot pushed a commit that referenced this issue Jun 17, 2024
…yaml better + tweak unhandled exception text

Fixes the main issues at #55987

Change-Id: I5b86f7c0df4017c02b96e67d8d8d03b71933b318
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371861
Reviewed-by: Sam Rawlins <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Brian Wilkerson <[email protected]>
@DanTup
Copy link
Collaborator

DanTup commented Jun 18, 2024

Some slight changes to what I noted above, with the latest change errors in analysis_options/pubspec are prioritized and shown first with an additional message:

Analyzing myapp...

Errors were found in 'pubspec.yaml' and/or 'analysis_options.yaml' which might result in either invalid diagnostics being produced or valid diagnostics being missed.

  error • analysis_options.yaml:3:1 • Expected ':'. • parse_error

Errors in remaining files.

  error • lib\main.dart:1:16 • A value of type 'Null' can't be returned from the function 'foo' because it has a return type of 'int'. • return_of_invalid_type

2 issues found.

@lucasjinreal
Copy link

I have no idea why it got this error:

dart analyze
Analyzing neso_flutter...
An unexpected error was encountered by the Analysis Server.
Please file an issue at https://github.com/dart-lang/sdk/issues/new/choose with the following details:

Internal error: Failed to handle request: analysis.setAnalysisRoots
type 'Null' is not a subtype of type 'Object' in type cast
#0      YamlNodeExtension.valueOrThrow (package:analyzer/src/util/yaml.dart:147:36)
#1      _LintConfig.asString (package:analyzer/src/lint/config.dart:93:47)
#2      _LintConfig._parseYaml.<anonymous closure> (package:analyzer/src/lint/config.dart:136:29)
#3      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)
#4      MapView.forEach (dart:collection/maps.dart:347:10)
#5      _LintConfig._parseYaml (package:analyzer/src/lint/config.dart:117:16)
#6      new LintConfig.parseMap (package:analyzer/src/lint/config.dart:38:62)
#7      parseConfig (package:analyzer/src/lint/config.dart:15:25)
#8      AnalysisOptionsImplExtensions.applyOptions (package:analyzer/src/analysis_options/apply_options.dart:229:18)
#9      ContextBuilderImpl._createOptionsMap (package:analyzer/src/dart/analysis/context_builder.dart:210:15)
#10     ContextBuilderImpl.createContext (package:analyzer/src/dart/analysis/context_builder.dart:135:15)
#11     new AnalysisContextCollectionImpl (package:analyzer/src/dart/analysis/analysis_context_collection.dart:108:36)
#12     ContextManagerImpl._createAnalysisContexts.performContextRebuildGuarded.performContextRebuild (package:analysis_server/src/context_manager.dart:549:40)
<asynchronous suspension>
#13     ContextManagerImpl._createAnalysisContexts.performContextRebuildGuarded (package:analysis_server/src/context_manager.dart:694:11)
<asynchronous suspension>
#14     _CancellingTaskQueue.queue.<anonymous closure> (package:analysis_server/src/context_manager.dart:978:15)
<asynchronous suspension>
#15     ContextManagerImpl.setRoots (package:analysis_server/src/context_manager.dart:364:5)
<asynchronous suspension>
#16     LegacyAnalysisServer.setAnalysisRoots (package:analysis_server/src/legacy_analysis_server.dart:792:9)
<asynchronous suspension>
#17     AnalysisSetAnalysisRootsHandler.handle (package:analysis_server/src/handler/legacy/analysis_set_analysis_roots.dart:46:7)
<asynchronous suspension>
#18     LegacyAnalysisServer.handleRequest.<anonymous closure>.<anonymous closure> (package:analysis_server/src/legacy_analysis_server.dart:576:11)
<asynchronous suspension>
#19     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:14)
<asynchronous suspension>
#20     LegacyAnalysisServer.handleRequest.<anonymous closure> (package:analysis_server/src/legacy_analysis_server.dart:557:7)
<asynchronous suspension>

the flutter master sitll have this issue, how to resolve it?

@DanTup
Copy link
Collaborator

DanTup commented Aug 19, 2024

@lucasjinreal that looks like a slightly different error - could you file a new issue with a copy of your analysis_options.yaml file that triggers this? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-analysis-options area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. area-dart-cli Use area-dart-cli for issues related to the 'dart' command like tool. dart-cli-analyze Issues related to the 'dart analyze' tool
Projects
None yet
Development

No branches or pull requests

6 participants