Skip to content

Conversation

maneesht
Copy link
Contributor

@maneesht maneesht commented Sep 8, 2025

@maneesht maneesht changed the title Fixed issue where if path was empty on web, the app crashed fix(fdc): issue where if path was empty on web, the app crashed Sep 8, 2025
@wer-mathurin
Copy link
Contributor

wer-mathurin commented Sep 9, 2025

@cynthiajoan , @yuchenshi @Lyokone
I saw this PR link to another ticket. My case is the app will crash if the errors key is missing in the JSON :-)

Also, I see other potential bugs in the code that need your attention and this can be solved by using the pattern matching otherwise we can have all other bunch of potential runtime exception.

instead of this:

List<DataConnectOperationFailureResponseErrorInfo> suberrors =
            handleErrors(bodyJson['errors']) <----- If the errors key is missing a runtime exception will be thrown (this is our case in another ticket)
                .map<DataConnectOperationFailureResponseErrorInfo>((e) =>
                    DataConnectOperationFailureResponseErrorInfo(
                        e.path != null
                            ? e.path!
                                .map((val) => val is String
                                    ? DataConnectFieldPathSegment(val)
                                    : DataConnectListIndexPathSegment(val))
                                .toList()
                            : [].cast<DataConnectPathSegment>(),
                        e.message))
                .toList();

In the handleError you have the same issue...you are assuming the keys in the json will be present

  List<JsonGraphqlResponseError> handleErrors(List<dynamic> errors) {
    return errors
        .map((eMap) => JsonGraphqlResponseError(eMap['message'], eMap['path']))
        .toList();
  }

Maybe in the JsonGraphqlResponseError you can change the variables to be nullable or throw an explicit error, because the error can be either a null runtime exception or a type cast exception!

Here is an example of how you can achieve the same without creating new methods and new class...so this will be more efficient because we do not need to instantiate a class to only pass data...Im not sure about the DataConnectRestContractException, but this in my opinion will help your team making sure the contract is respected with the backend and can be catch in your integration tests :-)

  <DataConnectOperationFailureResponseErrorInfo>[
    for (final {'path': List paths, 'message': String? message}
        in bodyJson['errors'] ?? [])
      DataConnectOperationFailureResponseErrorInfo(
        [
          for (final val in paths)
            switch (val) {
              String() => DataConnectFieldPathSegment(val),
              int() => DataConnectListIndexPathSegment(val),
              _ => throw DataConnectRestContractException(
                'The val must be either a String or an Int. The current val is  ${val.runtimeType}',
              ),
            },
        ],
        message ??
            (throw DataConnectRestContractException(
              'Message should contain the error',
            )),
      ),
  ];

@maneesht
Copy link
Contributor Author

maneesht commented Sep 9, 2025

@wer-mathurin The errors field should always be sent. Can you give me an example where the errors field is not present in the JSON?

@maneesht
Copy link
Contributor Author

maneesht commented Sep 9, 2025

@wer-mathurin we also do a check above that function to check whether the errors field is added:https://github.com/firebase/flutterfire/pull/17704/files#diff-3cec4d6d4680bc84d9864bd72e0fa5907325afe63b62f08cd9041d5a7656a56aR131

@wer-mathurin
Copy link
Contributor

wer-mathurin commented Sep 9, 2025

@wer-mathurin we also do a check above that function to check whether the errors field is added:https://github.com/firebase/flutterfire/pull/17704/files#diff-3cec4d6d4680bc84d9864bd72e0fa5907325afe63b62f08cd9041d5a7656a56aR131

In this case my suggestion is even more appealing, because you can remove the if....less indentations equal a more readable code :-). And I think using pattern matching over imbricated if statements is a cleaner approach.

@wer-mathurin The errors field should always be sent. Can you give me an example where the errors field is not present in the JSON?

This is why I'm suggesting to add a DataConnectRestContractException...this will shield the Dart SDK from contract change from the DataConnect backend...if they decided to change the response format...the SDK will fail to read those "always sent" keys in the JSON. But you need to have an Integration test for that.

@maneesht
Copy link
Contributor Author

maneesht commented Sep 9, 2025

@wer-mathurin Thanks for your suggestion. Though I will say, the if block is more legible for those who aren't necessarily familiar with Dart. I'll take your comments under consideration

@wer-mathurin
Copy link
Contributor

@wer-mathurin Thanks for your suggestion. Though I will say, the if block is more legible for those who aren't necessarily familiar with Dart. I'll take your comments under consideration

I was thinking that the the code in the Dart SDK is maintained or contributed was done by people familiar with the Dart language :-)

For the JSON validation and data extraction this is one of the use case documented by the Dart team : https://dart.dev/language/patterns#validating-incoming-json

Cheers,
Looking to see this PR merged whatever the way it's done, at least we are going forward.

@maneesht
Copy link
Contributor Author

@wer-mathurin Updated the PR. The new changes should be similar to what you suggested

@maneesht maneesht merged commit e9a6c04 into main Sep 11, 2025
27 of 30 checks passed
@maneesht maneesht deleted the mtewani/fix-id-error branch September 11, 2025 15:49
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.

Data Connect Dart SDK fail to handle errors return by the connector
5 participants