Graphql-flutter: SocketException is unusable

Created on 4 Jul 2019  Â·  12Comments  Â·  Source: zino-app/graphql-flutter

Describe the bug
SocketException are converted into a GraphQL error, but then unfortunately are almost unusable, since the message string is empty.

To Reproduce
Steps to reproduce the behavior:

  1. Send a query to an IP address without a server.
  2. Catch GraghQL Error and see that the message string is empty

Expected behavior
First I expected that the SocketException will be thrown directly and I can catch it. But since it is wrapped around a GraphQL own exception, I expected that you could use the GraphQL exception to find out which exception was thrown originally.

Screenshots
Screenshot 2019-07-04 at 20 59 02
When trying to wrap the exception you can see that the message string of a SocketException is empty. This makes the GraphQL exception unusable. (One could check for empty messages and then hope that it is a SocketException, but thats risky)

Version
I use the Flutter version v1.6.3 and the GraphlQl-Flutter version 1.1.1-beta.8.

All 12 comments

In your example, do you expect "OS Error: Connection timedout, errno = 110"?

Hmm best would be directly the SocketException, but otherwise the more information the better. Would therefore say "SocketException: OS Error: Connection timed out = 110, address = 10.101.1249, port 59768" so I guess error.toString().

https://github.com/zino-app/graphql-flutter/pull/359 @friebetill this PR will actually just throw the original SocketException

closed by #359

@micimize I have a issue with this fix in v2.0.1.

I get the following error when using the Query Widget and try the 'no connection' scenario:

Performing hot restart...                                               

Restarted application in 3.928ms.
flutter: is loading
flutter: [SocketException, SocketException: OS Error: Connection refused, errno = 61, address = localhost, port = 64486]
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: SocketException: OS Error: Connection refused, errno = 61, address = localhost, port = 64486
#0      QueryManager._attemptToWrapError (package:graphql/src/core/query_manager.dart:239:7)
#1      QueryManager._resolveQueryOnNetwork (package:graphql/src/core/query_manager.dart:140:28)
<asynchronous suspension>
#2      QueryManager.fetchQueryAsMultiSourceResult (package:graphql/src/core/query_manager.dart:90:17)
#3      ObservableQuery.fetchResults (package:graphql/src/core/observable_query.dart:116:22)
#4      new ObservableQuery (package:graphql/src/core/observable_query.dart:31:7)
#5      QueryManager.watchQuery (package:graphql/src/core/query_manager.dart:45:45)
#6      GraphQLClient.watchQuery (package:graphql/src/graphql_client.dart:38:25)
#7      QueryState._initQuery (package:graphql_flutter/src/widgets/query.dart:58:30)
#8      QueryState.didChangeDependencies (package:graphql_flutter/src/widgets/query.dart:64:5)
#9      StatefulElement._fir<…>

How to catch the SocketException in this example widget?

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';

class Profile extends StatelessWidget {
  const Profile();

  @override
  Widget build(BuildContext context) {
    return Query(
      options: QueryOptions(
        document: '''
          query CurrentUser {
            currentUser {
                __typename
                id
                username
                email
            }
        }
        '''
      ),

      builder: (QueryResult result, {BoolCallback refetch}) {
        if (result.errors != null) {
          print('retrieved errors');
          print(result.errors.toString());
          return Text(result.errors.toString());
        }

        if (result.loading) {
          print('is loading');
          return Center(
            child: const CircularProgressIndicator(),
          );
        }
        print('retrieved profile data');
        return Column(
          children: <Widget>[
            Text(JsonEncoder.withIndent('  ').convert(result.data)),
            RaisedButton(
              onPressed: refetch,
              child: const Text('REFETCH'),
            ),
          ],
        );
      },
    );
  }
}

@Gerrel I think you'll want something like https://github.com/jhomlala/catcher for now

ah thanks did not know this nifty library.

Hey, was wondering how can you try catch the SocketException error.

When using ...

try {
  await getGraphQLClient().query(_queryOptions(phoneNumber));
} catch (e) {
  return null;
}

it doesn't get caught. I get "Unhandled Exception: SocketException: OS Error: Connection refused, errno = 61, address = localhost, port = 55657"

@ryankauk it is converted into a graphql error and added to the list of errors on the QueryResult

@micimize The application crashes because of the error, if it's added to the graphql list of errors then it shouldn't be thrown like the rest of them, I had to make my own graphql link in order to listen to forward(operation) stream and on the error handler add to the stream (adding error to graphql) to remove it's error output.

@ryankauk hmm, then I'm not sure. Try debugging further and open a separate issue with more information (preferably off of beta).
But at a glance, it doesn't look to me like the error can be from that block. IDK how it'd crash your app without throwing something

@micimize alright I made an issue with a repo to show the issue. #380

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vanelizarov picture vanelizarov  Â·  3Comments

jomag picture jomag  Â·  3Comments

javi11 picture javi11  Â·  3Comments

smkhalsa picture smkhalsa  Â·  3Comments

campanagerald picture campanagerald  Â·  3Comments