-
Notifications
You must be signed in to change notification settings - Fork 21
feat: Dart SDK update for version 18.2.0 #92
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
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThe PR bumps the SDK version from 18.1.0 to 18.2.0 across README, pubspec.yaml, and client headers/user-agent. It introduces new enums (attribute, index, deployment, execution, health, message statuses/triggers) by adding parts to enums.dart and importing enums in models.dart. Multiple model fields switch from String to corresponding enum types, with updated fromMap/toMap to map enum values. Tests are updated to use enums. Additionally, Document, Preferences, and Row fromMap now read data from map["data"] when present, otherwise fall back to the whole map. Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🔇 Additional comments (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
lib/src/models/attribute_relationship.dart (1)
68-90
: Handle unknown attribute statuses without throwing.
firstWhere
without anorElse
will now throw aStateError
if the backend introduces a new status string. Previously this field was just aString
, so the SDK stayed resilient to forward-compatible values. Please add a graceful fallback (even if it defaults to a sentinel) so deserialization keeps working instead of crashing.- status: enums.AttributeStatus.values.firstWhere( - (e) => e.value == map['status'], - ), + status: map['status'] != null + ? enums.AttributeStatus.values.firstWhere( + (e) => e.value == map['status'], + orElse: () => enums.AttributeStatus.available, + ) + : enums.AttributeStatus.available,lib/src/models/deployment.dart (1)
1-181
: AddorElse
fallbacks to enum parsing in models
AllfromMap
methods under lib/src/models usevalues.firstWhere
without anorElse
, which throws aStateError
if the mapped value is missing. Update each call to include anorElse
that returns a default enum or throws a descriptive error.
🧹 Nitpick comments (28)
test/src/models/index_test.dart (1)
29-29
: Optionally assert wire value in map.Add expect(map['status'], 'available') to also validate serialization.
test/src/models/attribute_email_test.dart (1)
24-24
: Optionally verify toMap outputs the string value.Add expect(map['status'], 'available') for the wire format check.
test/src/models/attribute_enum_test.dart (1)
25-25
: Optional: assert serialized wire value too.Add expect(map['status'], 'available') to cover encoding.
test/src/models/message_test.dart (1)
34-34
: Optional: include a wire-format check.Add expect(map['status'], 'draft') to assert toMap emits the correct string.
lib/src/enums/health_antivirus_status.dart (1)
3-13
: Enum definition looks good; consider centralizing parsing with fallback.Multiple models do
values.firstWhere(...)
for this enum. Add a parse helper to avoid duplication and to define a single fallback policy for unknown values.Apply this diff to add a parsing helper:
enum HealthAntivirusStatus { disabled(value: 'disabled'), offline(value: 'offline'), online(value: 'online'); const HealthAntivirusStatus({required this.value}); final String value; String toJson() => value; + + static HealthAntivirusStatus parse(String? raw, {HealthAntivirusStatus fallback = HealthAntivirusStatus.disabled}) { + for (final v in HealthAntivirusStatus.values) { + if (v.value == raw) return v; + } + return fallback; + } }test/src/models/health_status_test.dart (1)
8-20
: LGTM; add a serialization assertion.Also assert that toMap serializes the enum back to the raw API value.
final map = model.toMap(); + expect(map['status'], 'pass'); final result = HealthStatus.fromMap(map);
lib/src/models/attribute_enum.dart (2)
56-58
: Gracefully handle unknown status strings from the API.
firstWhere
withoutorElse
throwsStateError
, breaking deserialization if the server rolls out new values. Add an explicitorElse
with a clear error (or a chosen fallback if you prefer).- status: enums.AttributeStatus.values.firstWhere( - (e) => e.value == map['status'], - ), + status: enums.AttributeStatus.values.firstWhere( + (e) => e.value == map['status'], + orElse: () => throw ArgumentError('Unknown AttributeStatus: ${map['status']}'), + ),
64-65
: Prefer typed list conversion for elements.Make the conversion explicitly typed to avoid runtime surprises.
- elements: List.from(map['elements'] ?? []), + elements: List<String>.from(map['elements'] ?? const []),lib/src/models/health_status.dart (2)
20-22
: Add explicitorElse
for forward-compat.Avoid
StateError
on new/unknown values; fail with a clear message or decide on a fallback.- status: enums.HealthCheckStatus.values.firstWhere( - (e) => e.value == map['status'], - ), + status: enums.HealthCheckStatus.values.firstWhere( + (e) => e.value == map['status'], + orElse: () => throw ArgumentError('Unknown HealthCheckStatus: ${map['status']}'), + ),
19-19
: Normalize numeric type forping
.APIs may send numbers as
num/double
. Coerce safely.- ping: map['ping'], + ping: (map['ping'] as num).toInt(),lib/src/models/attribute_boolean.dart (1)
48-50
: AddorElse
to prevent runtimeStateError
on unknown statuses.Same rationale as other models.
- status: enums.AttributeStatus.values.firstWhere( - (e) => e.value == map['status'], - ), + status: enums.AttributeStatus.values.firstWhere( + (e) => e.value == map['status'], + orElse: () => throw ArgumentError('Unknown AttributeStatus: ${map['status']}'), + ),lib/src/models/health_antivirus.dart (1)
16-18
: AddorElse
for unknown antivirus status values.Prevents brittle deserialization when API adds new statuses.
- status: enums.HealthAntivirusStatus.values.firstWhere( - (e) => e.value == map['status'], - ), + status: enums.HealthAntivirusStatus.values.firstWhere( + (e) => e.value == map['status'], + orElse: () => throw ArgumentError('Unknown HealthAntivirusStatus: ${map['status']}'), + ),test/src/models/attribute_integer_test.dart (1)
18-24
: Add toMap round-trip check for the wire value.Catches accidental changes to serialization.
final map = model.toMap(); + expect(map['status'], 'available'); final result = AttributeInteger.fromMap(map);
test/src/models/attribute_url_test.dart (1)
19-21
: Also assert serialized value in map to catch (de)serialization regressions.Round-tripping only can mask bugs if both sides use the same wrong key/value. Add a direct check on the map.
Apply this diff:
final map = model.toMap(); + expect(map['status'], AttributeStatus.available.value); final result = AttributeUrl.fromMap(map);
test/src/models/deployment_test.dart (1)
38-40
: Assert raw map serialization for status.Prevents silent mismatch between enum and wire value.
Apply this diff:
final map = model.toMap(); + expect(map['status'], DeploymentStatus.waiting.value); final result = Deployment.fromMap(map);
test/src/models/attribute_polygon_test.dart (1)
18-20
: Add a direct map assertion for status serialization.Apply this diff:
final map = model.toMap(); + expect(map['status'], AttributeStatus.available.value); final result = AttributePolygon.fromMap(map);
test/src/models/attribute_ip_test.dart (1)
18-21
: Verify map serialization for status.Apply this diff:
final map = model.toMap(); + expect(map['status'], AttributeStatus.available.value); final result = AttributeIp.fromMap(map);
lib/src/models/attribute_ip.dart (3)
52-55
: Harden enum parsing against unknown values and nulls.firstWhere without orElse throws on unknown/new server values; map['status'] can also be null. Add a safe fallback to avoid runtime exceptions and improve forward-compat.
Apply this diff:
- status: enums.AttributeStatus.values.firstWhere( - (e) => e.value == map['status'], - ), + status: enums.AttributeStatus.values.firstWhere( + (e) => e.value == map['status'], + orElse: () => enums.AttributeStatus.failed, // fallback; pick a sensible default if you prefer another + ),Optionally, consider adding an explicit Unknown case in AttributeStatus for true forward compatibility.
55-62
: Avoid serializing null error as string "null".Current toString() on a null error yields "null", which is misleading. Use a default empty string or make the field nullable if the public API allows it.
Apply this diff:
- error: map['error'].toString(), + error: map['error']?.toString() ?? '',
48-63
: Audit and safeguard enum parsing across models
There are dozens ofEnum.values.firstWhere(...)
calls in model factories (e.g. attribute_*.dart, index.dart, message.dart, deployment.dart, execution.dart) without anorElse
, which will throw if the API returns an unexpected value. Add anorElse
fallback (or introduce a helper) to handle missing/unknown values consistently.test/src/models/attribute_point_test.dart (1)
18-20
: Add direct assertion for serialized status.Apply this diff:
final map = model.toMap(); + expect(map['status'], AttributeStatus.available.value); final result = AttributePoint.fromMap(map);
test/src/models/attribute_boolean_test.dart (1)
18-20
: Add explicit map check for status serialization.Apply this diff:
final map = model.toMap(); + expect(map['status'], AttributeStatus.available.value); final result = AttributeBoolean.fromMap(map);
test/src/models/execution_test.dart (1)
28-30
: Also assert serialized wire values for enums.Ensures toMap emits the expected strings.
Apply this diff:
final map = model.toMap(); + expect(map['trigger'], ExecutionTrigger.http.value); + expect(map['status'], ExecutionStatus.waiting.value); final result = Execution.fromMap(map);lib/src/enums/message_status.dart (1)
10-15
: Add a static parser to centralize safe deserialization.Provide MessageStatus.fromJson/tryParse to avoid repeating values.firstWhere in models and to enable graceful fallback handling.
Apply this diff:
const MessageStatus({required this.value}); final String value; + static MessageStatus? fromJson(String? value) { + if (value == null) return null; + for (final e in MessageStatus.values) { + if (e.value == value) return e; + } + return null; + } + String toJson() => value;lib/src/enums/deployment_status.dart (1)
10-15
: Provide a static fromJson/tryParse for reuse.Helps eliminate scattered firstWhere calls and supports tolerant parsing.
Apply this diff:
const DeploymentStatus({required this.value}); final String value; + static DeploymentStatus? fromJson(String? value) { + if (value == null) return null; + for (final e in DeploymentStatus.values) { + if (e.value == value) return e; + } + return null; + } + String toJson() => value;lib/src/models/attribute_string.dart (1)
64-64
: Ensure numeric type safety for JSON-decoded numbersJSON decoders yield num; assigning directly to int can fail at runtime. Coerce safely.
Apply this diff:
- size: map['size'], + size: (map['size'] as num).toInt(),lib/src/models/deployment.dart (2)
125-128
: Coerce numeric fields from num to int to avoid runtime type errorsJSON-decoded numeric values are num; direct assignment to int can fail. Convert explicitly.
Apply this diff:
- sourceSize: map['sourceSize'], - buildSize: map['buildSize'], - totalSize: map['totalSize'], + sourceSize: (map['sourceSize'] as num).toInt(), + buildSize: (map['buildSize'] as num).toInt(), + totalSize: (map['totalSize'] as num).toInt(), @@ - buildDuration: map['buildDuration'], + buildDuration: (map['buildDuration'] as num).toInt(),Also applies to: 136-136
48-49
: Docstring still lists raw string valuesOptional: reference enums.DeploymentStatus in the doc to reduce drift, e.g., “See enums.DeploymentStatus for possible values.”
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (54)
README.md
(1 hunks)lib/enums.dart
(1 hunks)lib/models.dart
(1 hunks)lib/query.dart
(0 hunks)lib/src/client_browser.dart
(1 hunks)lib/src/client_io.dart
(1 hunks)lib/src/enums/attribute_status.dart
(1 hunks)lib/src/enums/deployment_status.dart
(1 hunks)lib/src/enums/execution_status.dart
(1 hunks)lib/src/enums/execution_trigger.dart
(1 hunks)lib/src/enums/health_antivirus_status.dart
(1 hunks)lib/src/enums/health_check_status.dart
(1 hunks)lib/src/enums/index_status.dart
(1 hunks)lib/src/enums/message_status.dart
(1 hunks)lib/src/models/attribute_boolean.dart
(3 hunks)lib/src/models/attribute_datetime.dart
(3 hunks)lib/src/models/attribute_email.dart
(3 hunks)lib/src/models/attribute_enum.dart
(3 hunks)lib/src/models/attribute_float.dart
(3 hunks)lib/src/models/attribute_integer.dart
(3 hunks)lib/src/models/attribute_ip.dart
(3 hunks)lib/src/models/attribute_line.dart
(3 hunks)lib/src/models/attribute_point.dart
(3 hunks)lib/src/models/attribute_polygon.dart
(3 hunks)lib/src/models/attribute_relationship.dart
(3 hunks)lib/src/models/attribute_string.dart
(3 hunks)lib/src/models/attribute_url.dart
(3 hunks)lib/src/models/deployment.dart
(3 hunks)lib/src/models/execution.dart
(3 hunks)lib/src/models/health_antivirus.dart
(1 hunks)lib/src/models/health_status.dart
(1 hunks)lib/src/models/index.dart
(3 hunks)lib/src/models/message.dart
(3 hunks)pubspec.yaml
(1 hunks)test/query_test.dart
(0 hunks)test/src/models/attribute_boolean_test.dart
(3 hunks)test/src/models/attribute_datetime_test.dart
(3 hunks)test/src/models/attribute_email_test.dart
(3 hunks)test/src/models/attribute_enum_test.dart
(3 hunks)test/src/models/attribute_float_test.dart
(3 hunks)test/src/models/attribute_integer_test.dart
(3 hunks)test/src/models/attribute_ip_test.dart
(3 hunks)test/src/models/attribute_line_test.dart
(3 hunks)test/src/models/attribute_point_test.dart
(3 hunks)test/src/models/attribute_polygon_test.dart
(3 hunks)test/src/models/attribute_relationship_test.dart
(3 hunks)test/src/models/attribute_string_test.dart
(3 hunks)test/src/models/attribute_url_test.dart
(3 hunks)test/src/models/deployment_test.dart
(3 hunks)test/src/models/execution_test.dart
(3 hunks)test/src/models/health_antivirus_test.dart
(1 hunks)test/src/models/health_status_test.dart
(2 hunks)test/src/models/index_test.dart
(3 hunks)test/src/models/message_test.dart
(3 hunks)
💤 Files with no reviewable changes (2)
- lib/query.dart
- test/query_test.dart
🔇 Additional comments (62)
lib/src/client_browser.dart (1)
33-35
: Header version bump aligns with 18.2.0 release.
Matches the updated package version and keeps HTTP metadata consistent.pubspec.yaml (1)
2-2
: Package version updated to 18.2.0 — looks good.
Keeps the manifest in sync with the new SDK release.README.md (1)
26-26
: Documentation dependency pin now matches 18.2.0.
Ensures users pull the latest SDK version.lib/src/client_io.dart (1)
39-42
: IO client headers updated cleanly.
The x-sdk-version and user-agent strings correctly reflect 18.2.0.lib/src/enums/index_status.dart (1)
3-15
: IndexStatus enum addition looks solid.
Covers all expected lifecycle states and preserves JSON serialization viavalue
.lib/src/enums/attribute_status.dart (1)
3-15
: AttributeStatus enum wired up correctly.
Provides the necessary states with consistent string serialization.lib/enums.dart (1)
28-35
: New enum parts exported appropriately.
Keeps the enums library authoritative for all status/trigger types.lib/models.dart (1)
4-5
: Importing enums.dart ensures models share the enum namespace.
The alias lets part files reference the new enum types cleanly.lib/src/models/attribute_url.dart (2)
12-12
: Good move to a typed status.Switching to enums.AttributeStatus improves type-safety and discoverability.
69-69
: Correct serialization of enum wire value.Emitting status.value is the right wire format.
lib/src/models/message.dart (2)
42-42
: Typed status is a solid improvement.Using enums.MessageStatus tightens the API.
94-94
: Good: serialize enum as its string value.status.value matches the API contract.
lib/src/models/attribute_line.dart (2)
12-12
: Enum-backed status aligns with the new model strategy.Looks good.
64-64
: Correct: emit the enum’s wire value.status.value is appropriate.
lib/src/models/attribute_float.dart (2)
12-12
: Type-safety improvement acknowledged.Using enums.AttributeStatus is consistent across models.
74-74
: OK on emitting the enum value.Matches the expected wire format.
test/src/models/index_test.dart (2)
2-2
: Correct import for enums.Needed for IndexStatus usage.
15-15
: Using IndexStatus improves test clarity.Good switch from string literal to enum.
test/src/models/attribute_email_test.dart (2)
2-2
: Enums import looks correct.
12-12
: Constructor now uses AttributeStatus as expected.test/src/models/attribute_enum_test.dart (2)
2-2
: Enums import is appropriate.
12-12
: Good: enum value in the model under test.test/src/models/message_test.dart (2)
2-2
: Enums import is needed and correct.
19-19
: Using MessageStatus.draft is correct.lib/src/models/health_antivirus.dart (1)
23-23
: LGTM on serialization.Enum serializes to its wire value. Consistent with tests.
test/src/models/attribute_integer_test.dart (1)
8-16
: LGTM; mirrors the enum-based API.Construction aligns with new enum-typed status.
test/src/models/attribute_url_test.dart (2)
2-2
: Import of enums is correct.Enum-based API usage in tests aligns with the model changes.
11-12
: Good migration to enums in constructor and assertions.Status now correctly uses AttributeStatus.available.
Also applies to: 24-24
test/src/models/deployment_test.dart (2)
2-2
: Enums import looks good.Required for DeploymentStatus usage.
23-23
: Enum-based status usage is correct.Matches model changes to DeploymentStatus.
Also applies to: 55-55
test/src/models/attribute_polygon_test.dart (2)
2-2
: Enums import is appropriate.
11-11
: Correct enum usage for status.Also applies to: 23-23
test/src/models/attribute_ip_test.dart (2)
2-2
: Enums import is appropriate.
11-11
: Correct enum usage for status.Also applies to: 24-24
lib/src/models/attribute_ip.dart (2)
11-13
: Enum type migration LGTM.Public surface now exposes enums.AttributeStatus, consistent with the SDK-wide change.
65-78
: toMap enum serialization is correct.Uses status.value as expected.
test/src/models/attribute_point_test.dart (2)
2-2
: Enums import is appropriate.
11-11
: Correct enum usage for status.Also applies to: 23-23
test/src/models/attribute_boolean_test.dart (2)
2-2
: Enums import is appropriate.
11-11
: Enum-based status checks look good.Also applies to: 23-23
test/src/models/execution_test.dart (2)
2-2
: Enums import is appropriate.
15-16
: Enum usage for trigger and status is correct.Also applies to: 37-38
lib/src/enums/health_check_status.dart (1)
3-12
: Enum serialization looks solid.
Enum values map cleanly to the wire format andtoJson
keeps the payload stable.test/src/models/attribute_datetime_test.dart (1)
2-24
: Test update matches the enum-backed status change.
The model round-trip now asserts againstAttributeStatus.available
, aligning with the new API surface.test/src/models/attribute_string_test.dart (1)
2-25
: Enum usage exercised correctly.
The test now mirrors the enum-based status contract and still validates the round-trip.test/src/models/attribute_float_test.dart (1)
2-24
: Round-trip covers the enum migration.
Happy path continues to pass while verifyingAttributeStatus.available
.lib/src/enums/execution_trigger.dart (1)
3-12
: Trigger enum is wired correctly.
String values line up with the documented API states and serialize as expected.test/src/models/attribute_relationship_test.dart (1)
2-30
: Test aligns with the enum-backed model.
Ensures the relationship attribute continues to round-trip through the new enum field.lib/src/enums/execution_status.dart (1)
3-13
: Status enum mirrors backend states.
Values and serialization look correct for the execution lifecycle.lib/src/enums/message_status.dart (1)
3-15
: Solid enum with JSON value mapping.Enum members, value field, and toJson look correct and consistent with other enums.
lib/src/enums/deployment_status.dart (1)
3-15
: LGTM: enum design mirrors the established pattern.Consistent value-carrying enum with toJson; aligns with SDK serialization.
lib/src/models/attribute_email.dart (1)
12-12
: Type migration to enums improves type-safety.Good move from String to enums.AttributeStatus.
lib/src/models/index.dart (1)
21-21
: Enum-typed status is appropriate.Improves correctness over free-form strings.
lib/src/models/attribute_integer.dart (1)
12-12
: Enum-typed status: nice upgrade.Keeps API consistent with other Attribute* models.
lib/src/models/execution.dart (2)
24-28
: Enum migration for trigger/status looks good.Consistent with new ExecutionTrigger/ExecutionStatus API.
119-120
: Correct JSON emission.Using .value ensures stable wire format.
test/src/models/attribute_line_test.dart (1)
2-2
: Enums migration in test looks correctImports and assertions updated to enum-backed status are consistent with the model changes.
Also applies to: 11-11, 23-23
lib/src/models/attribute_polygon.dart (2)
12-12
: Public API type change — confirm semver and migration docsstatus changed from String to enums.AttributeStatus. Ensure this is called out in the 18.2.0 release notes with migration guidance.
64-64
: Correct enum serializationSerializing as status.value is correct and interoperable with the API.
lib/src/models/attribute_datetime.dart (1)
69-69
: Enum to string mapping looks goodstatus.value in toMap maintains wire-compatibility.
test/src/models/health_antivirus_test.dart (1)
2-2
: Test updates align with enum-backed statusConstruction and assertions now use HealthAntivirusStatus; looks good.
Also applies to: 10-10, 17-17
lib/src/models/attribute_string.dart (1)
75-75
: Enum serialization is correctstatus.value preserves the original wire format.
status: enums.AttributeStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard enum parsing against unknown values
Same issue as other models: firstWhere without orElse may throw. Add a fallback.
Apply this diff:
- status: enums.AttributeStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: enums.AttributeStatus.values.firstWhere(
+ (e) => e.value == map['status']?.toString(),
+ orElse: () => enums.AttributeStatus.values.first,
+ ),
Also consider introducing an explicit Unknown enum value across status enums and using that here.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
status: enums.AttributeStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
), | |
status: enums.AttributeStatus.values.firstWhere( | |
(e) => e.value == map['status']?.toString(), | |
orElse: () => enums.AttributeStatus.values.first, | |
), |
🤖 Prompt for AI Agents
In lib/src/models/attribute_datetime.dart around lines 52 to 54, the enum
parsing uses firstWhere without an orElse and can throw for unknown values; fix
by providing an orElse that returns a safe fallback (preferably an explicit
Unknown/UnknownValue member on enums.AttributeStatus if available, otherwise a
sensible default like enums.AttributeStatus.<default>) so parsing never throws;
update the code to use firstWhere(..., orElse: () =>
enums.AttributeStatus.Unknown) (and add an explicit Unknown enum value to the
status enums if not already present and use that as the fallback).
status: enums.AttributeStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), | ||
error: map['error'].toString(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Guard against unknown/forward-compatible status values.
values.firstWhere(...) without orElse throws when API returns a new/unknown status, causing runtime failures. Add a fallback or route through a safe parser.
Apply this diff as a minimal hardening (adjust fallback if product semantics differ):
- status: enums.AttributeStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: enums.AttributeStatus.values.firstWhere(
+ (e) => e.value == map['status'],
+ orElse: () => enums.AttributeStatus.failed,
+ ),
Run to locate other risky firstWhere enum parses to update similarly:
🏁 Script executed:
#!/bin/bash
rg -nP --type=dart -C2 'values\.firstWhere\s*\('
Length of output: 7263
Add orElse
fallback to enum parsing in model classes
All .values.firstWhere((e) => e.value == map['status'])
calls in lib/src/models/*.dart
must include an orElse
handler returning a safe default to prevent exceptions on unknown API values. For example:
- enums.AttributeStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ enums.AttributeStatus.values.firstWhere(
+ (e) => e.value == map['status'],
+ orElse: () => enums.AttributeStatus.failed,
+ ),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
status: enums.AttributeStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
), | |
error: map['error'].toString(), | |
status: enums.AttributeStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
orElse: () => enums.AttributeStatus.failed, | |
), | |
error: map['error'].toString(), |
🤖 Prompt for AI Agents
In lib/src/models/attribute_email.dart around lines 52 to 55, the enum parsing
call using .values.firstWhere((e) => e.value == map['status']) can throw if the
API returns an unexpected value; update the firstWhere to include an orElse
handler that returns a safe default (for example enums.AttributeStatus.unknown
if that variant exists, otherwise enums.AttributeStatus.values.first) so the
model never throws when encountering unknown status values.
status: enums.AttributeStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Prevent runtime StateError on unexpected/null status.
Add explicit orElse with a clear error.
Apply this diff:
- status: enums.AttributeStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: (() {
+ final value = map['status']?.toString();
+ return enums.AttributeStatus.values.firstWhere(
+ (e) => e.value == value,
+ orElse: () => throw ArgumentError.value(value, 'status', 'Unknown AttributeStatus'),
+ );
+ })(),
Run this script to find any other enum parsers missing orElse:
🏁 Script executed:
#!/bin/bash
# Find enum `values.firstWhere(` calls without an `orElse:` across the lib.
rg -nP --type=dart -C2 '(AttributeStatus|MessageStatus|IndexStatus|DeploymentStatus|ExecutionStatus|HealthStatus)\.values\.firstWhere\s*\((?![^)]*orElse)' lib
Length of output: 84
🏁 Script executed:
#!/usr/bin/env bash
python3 - <<'PYCODE'
import re, glob
patterns = ['AttributeStatus', 'MessageStatus', 'IndexStatus', 'DeploymentStatus', 'ExecutionStatus', 'HealthStatus']
for filepath in glob.glob('lib/**/*.dart', recursive=True):
with open(filepath, 'r', encoding='utf-8') as f:
code = f.read()
for pat in patterns:
for match in re.finditer(rf'\b{pat}\.values\.firstWhere\(', code):
start = match.end()
depth = 1
i = start
while i < len(code) and depth > 0:
if code[i] == '(':
depth += 1
elif code[i] == ')':
depth -= 1
i += 1
snippet = code[start:i]
if 'orElse' not in snippet:
lineno = code.count('\n', 0, match.start()) + 1
print(f'{filepath}:{lineno}')
PYCODE
Length of output: 644
Add explicit orElse
fallback to all enum parsing
- lib/src/models/attribute_boolean.dart:48
- lib/src/models/attribute_datetime.dart:52
- lib/src/models/attribute_email.dart:52
- lib/src/models/attribute_enum.dart:56
- lib/src/models/attribute_float.dart:56
- lib/src/models/attribute_integer.dart:56
- lib/src/models/attribute_ip.dart:52
- lib/src/models/attribute_line.dart:48
- lib/src/models/attribute_point.dart:48
- lib/src/models/attribute_polygon.dart:48
- lib/src/models/attribute_relationship.dart:68
- lib/src/models/attribute_string.dart:56
- lib/src/models/attribute_url.dart:52
- lib/src/models/deployment.dart:132
- lib/src/models/execution.dart:91
- lib/src/models/index.dart:55
- lib/src/models/message.dart:74
Wrap each values.firstWhere(…)
in a closure and add
orElse: () => throw ArgumentError.value(value, '…', 'Unknown ${EnumName}')
to prevent runtime StateError on null or unexpected values.
🤖 Prompt for AI Agents
In lib/src/models/attribute_float.dart around lines 56 to 58, the enum lookup
uses enums.AttributeStatus.values.firstWhere((e) => e.value == map['status'])
which can throw a StateError for unknown or null values; change it to use a
closure and provide an orElse that throws an ArgumentError.value with the
failing value and field name, e.g. enums.AttributeStatus.values.firstWhere((e)
=> e.value == map['status'], orElse: () => throw
ArgumentError.value(map['status'], 'status', 'Unknown AttributeStatus')), so
unexpected values produce a clear ArgumentError instead of a StateError.
status: enums.AttributeStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent StateError on unmapped status.
Add orElse to firstWhere to ensure robustness against future enum expansion.
Apply:
- status: enums.AttributeStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: enums.AttributeStatus.values.firstWhere(
+ (e) => e.value == map['status'],
+ orElse: () => enums.AttributeStatus.failed,
+ ),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
status: enums.AttributeStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
), | |
status: enums.AttributeStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
orElse: () => enums.AttributeStatus.failed, | |
), |
🤖 Prompt for AI Agents
In lib/src/models/attribute_integer.dart around lines 56 to 58, the call to
enums.AttributeStatus.values.firstWhere(...) can throw a StateError if
map['status'] doesn't match any enum; update firstWhere to supply an orElse that
returns a safe default (for example a dedicated unknown/unspecified enum member
if available, or enums.AttributeStatus.values.first) so unmatched statuses don't
crash the app.
status: enums.AttributeStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard against unknown status values during deserialization.
Add an orElse that throws a clear error to avoid opaque StateError.
Apply this diff:
- status: enums.AttributeStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: (() {
+ final value = map['status']?.toString();
+ return enums.AttributeStatus.values.firstWhere(
+ (e) => e.value == value,
+ orElse: () => throw ArgumentError.value(value, 'status', 'Unknown AttributeStatus'),
+ );
+ })(),
🤖 Prompt for AI Agents
In lib/src/models/attribute_line.dart around lines 48 to 50, the deserialization
uses enums.AttributeStatus.values.firstWhere without an orElse, which throws an
opaque StateError for unknown status values; update the firstWhere call to
include an orElse that throws a clear, descriptive exception (including the
received map['status'] and possibly the attribute name/context) so
unknown/invalid status values produce an explicit error message during
deserialization.
status: enums.AttributeStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle unknown/null status explicitly to avoid StateError at runtime.
values.firstWhere without orElse will throw if the server sends an unrecognized or null status. Add explicit handling with a clearer error.
Apply this diff:
- status: enums.AttributeStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: (() {
+ final value = map['status']?.toString();
+ return enums.AttributeStatus.values.firstWhere(
+ (e) => e.value == value,
+ orElse: () => throw ArgumentError.value(value, 'status', 'Unknown AttributeStatus'),
+ );
+ })(),
🤖 Prompt for AI Agents
In lib/src/models/attribute_url.dart around lines 52 to 54, the code uses
enums.AttributeStatus.values.firstWhere(...) without orElse which will throw a
generic StateError if map['status'] is null or unrecognized; update it to read
the raw status into a local var, then call firstWhere with an orElse that throws
a clearer error (e.g., include the raw status value) or returns a safe default
as appropriate for your domain, thereby preventing an unexpected runtime
StateError and providing a descriptive message when the server sends an
unknown/null status.
status: enums.DeploymentStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Protect enum parsing from unknown/novel status values
As elsewhere, firstWhere without orElse will throw. Add fallback to keep SDK forward-compatible with new server statuses.
Apply this diff:
- status: enums.DeploymentStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: enums.DeploymentStatus.values.firstWhere(
+ (e) => e.value == map['status']?.toString(),
+ orElse: () => enums.DeploymentStatus.values.first,
+ ),
Consider adding a DeploymentStatus.unknown and using it here across the SDK.
🤖 Prompt for AI Agents
In lib/src/models/deployment.dart around lines 132 to 134, the enum parsing uses
firstWhere without an orElse which will throw on unknown server statuses; add a
safe fallback by defining a DeploymentStatus.unknown value in the enums (if not
present) and change the parsing to use firstWhere with an orElse that returns
DeploymentStatus.unknown so unknown/novel status strings map to .unknown instead
of throwing, and propagate that .unknown value across the SDK where appropriate.
trigger: enums.ExecutionTrigger.values.firstWhere( | ||
(e) => e.value == map['trigger'], | ||
), | ||
status: enums.ExecutionStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Harden enum parsing for trigger and status.
Unknown values will currently throw; add safe fallbacks to avoid runtime crashes.
Apply:
- trigger: enums.ExecutionTrigger.values.firstWhere(
- (e) => e.value == map['trigger'],
- ),
- status: enums.ExecutionStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ trigger: enums.ExecutionTrigger.values.firstWhere(
+ (e) => e.value == map['trigger'],
+ orElse: () => enums.ExecutionTrigger.http,
+ ),
+ status: enums.ExecutionStatus.values.firstWhere(
+ (e) => e.value == map['status'],
+ orElse: () => enums.ExecutionStatus.processing,
+ ),
If preferred, expose static fromJson/tryParse on the enums and use those here for consistency.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
trigger: enums.ExecutionTrigger.values.firstWhere( | |
(e) => e.value == map['trigger'], | |
), | |
status: enums.ExecutionStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
), | |
trigger: enums.ExecutionTrigger.values.firstWhere( | |
(e) => e.value == map['trigger'], | |
orElse: () => enums.ExecutionTrigger.http, | |
), | |
status: enums.ExecutionStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
orElse: () => enums.ExecutionStatus.processing, | |
), |
🤖 Prompt for AI Agents
In lib/src/models/execution.dart around lines 88 to 93, the enum parsing uses
firstWhere without a fallback which will throw on unknown values; update both
trigger and status parsing to provide safe fallbacks (use firstWhere with an
orElse returning a sensible default enum value, e.g. a dedicated
Unknown/Unspecified value or the first/neutral enum entry) to avoid runtime
crashes; alternatively, implement and call static fromJson/tryParse helpers on
the enums that encapsulate this safe parsing behavior and return a default when
map values are unrecognized.
status: enums.IndexStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add fallback to avoid crashes on unknown status.
Same pitfall: firstWhere without orElse will throw for new server values.
Apply:
- status: enums.IndexStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: enums.IndexStatus.values.firstWhere(
+ (e) => e.value == map['status'],
+ orElse: () => enums.IndexStatus.failed,
+ ),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
status: enums.IndexStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
), | |
status: enums.IndexStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
orElse: () => enums.IndexStatus.failed, | |
), |
🤖 Prompt for AI Agents
In lib/src/models/index.dart around lines 55 to 57, the call to
enums.IndexStatus.values.firstWhere(...) will throw if the server returns an
unknown status; change it to call firstWhere with an orElse that returns a safe
default (preferably enums.IndexStatus.unknown if that enum value exists,
otherwise enums.IndexStatus.values.first) so unknown/forward-compatible statuses
don't crash parsing, and adjust downstream code to handle the chosen default if
necessary.
status: enums.MessageStatus.values.firstWhere( | ||
(e) => e.value == map['status'], | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add robust parsing with helpful error; consider tightening list typing.
- firstWhere without orElse will throw a generic StateError on unknown/null values. Prefer an explicit ArgumentError for clarity.
- Optional: For topics/users/targets/deliveryErrors, prefer List.from(...) to ensure strong typing.
Apply this diff for status:
- status: enums.MessageStatus.values.firstWhere(
- (e) => e.value == map['status'],
- ),
+ status: (() {
+ final value = map['status']?.toString();
+ return enums.MessageStatus.values.firstWhere(
+ (e) => e.value == value,
+ orElse: () => throw ArgumentError.value(value, 'status', 'Unknown MessageStatus'),
+ );
+ })(),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
status: enums.MessageStatus.values.firstWhere( | |
(e) => e.value == map['status'], | |
), | |
status: (() { | |
final value = map['status']?.toString(); | |
return enums.MessageStatus.values.firstWhere( | |
(e) => e.value == value, | |
orElse: () => throw ArgumentError.value( | |
value, | |
'status', | |
'Unknown MessageStatus', | |
), | |
); | |
})(), |
🤖 Prompt for AI Agents
In lib/src/models/message.dart around lines 74 to 76, replace the unsafe
enums.MessageStatus.values.firstWhere lookup with a version that supplies an
orElse which throws an ArgumentError with a clear message including the invalid
map['status'] value; also tighten list typing for
topics/users/targets/deliveryErrors by using List<String>.from(...) (or
null-aware variants) so the fields are strongly typed and avoid runtime type
errors.
This PR contains updates to the Dart SDK for version 18.2.0.
Summary by CodeRabbit