Skip to content

Explain why a value cannot be revived - #820

Open
Yusufihsangorgel wants to merge 4 commits into
dart-lang:masterfrom
Yusufihsangorgel:issue-411-revive-error
Open

Explain why a value cannot be revived#820
Yusufihsangorgel wants to merge 4 commits into
dart-lang:masterfrom
Yusufihsangorgel:issue-411-revive-error

Conversation

@Yusufihsangorgel

@Yusufihsangorgel Yusufihsangorgel commented Aug 2, 2026

Copy link
Copy Markdown

Fixes #411

reviveInstance ends with allResults.first, and that list is empty whenever it finds no candidate:

Bad state: No element
dart:core                                             List.first
package:source_gen/src/constants/revive.dart 105:21   reviveInstance
package:source_gen/src/constants/reader.dart 278:25   _DartObjectConstant.revive

revive() never passes an origin, so the scan runs over the library of the value's own type. That library is dart:core for a literal or a type, never the one the annotation was written in.

Unsupported operation: Cannot revive Type (String): it is not a const
constructor invocation, and no constant declaration for it was found in
library dart:core. Read a literal with `ConstantReader.literalValue` and
a type with `ConstantReader.typeValue`.

UnsupportedError is what @TekExplorer suggested, and what revive() already throws for a null constant. The dartdoc promised null here, which the non-nullable return never allowed; it now says what happens.

I looked for callers that catch the StateError. analyzer_buffer, the one #411 points to, catches everything with a bare catch, so only the text it wraps changes. mockito resolves this version but calls revive() after ruling out null, literals, and types (_addTypesFromConstant in builder.dart). sql_serializable branches on the error type (config.dart:136) but pins source_gen: ^1.2.6.

Version goes to 4.2.5-wip.

`reviveInstance` ends with `allResults.first`. When it finds no
candidate, the list is empty and the failure surfaces as
`Bad state: No element`, with nothing in it to act on.
`ConstantReader.revive()` always calls it without an `origin`, so the
scan runs over the library of the value's own type. That library is
`dart:core` for a literal or a type, never the one the annotation was
written in.

Throw an `UnsupportedError` naming the value, where it looked, and the
readers that do handle it. `ConstantReader.revive()` already throws
`UnsupportedError` for a null constant, so the two now agree. Whether
the method should return null instead is a separate, breaking question
and is left alone.
@TekExplorer

Copy link
Copy Markdown

I think that would close the issue
It simply is doing so in a non-breaking way :)
This way, any users will know why it failed and what to do about it.

While returning null as intended would have been preferred, that ship has mostly sailed after the non-null-by-default update seemingly completely missed this one for over 7 years.

So long as the dartdoc mentions the UnsupportedError ahead of time, I think that's all we really need.

The dartdoc landed on `reviveInstance`, which `source_gen.dart` does not
export, so it never renders on pub.dev. Callers reach this through
`ConstantReader.revive()`, and that one said nothing about the error.
`_NullConstant.revive()` throws the same error for a null constant, and the
first version only documented the missing-reference case.
`revive.dart` says the search for a reference came up empty; the class doc
said the value has no reference to recreate, which reads wider than what the
code checks.
@Yusufihsangorgel

Copy link
Copy Markdown
Author

Yeah, it has to be visible before the call. It was only on reviveInstance, which isn't exported, so I've put it on ConstantReader.revive() too. The error for a missing reference names the two alternatives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ConstantReader.revive() crashes when attempting to revive a type

2 participants