Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to send the intercepted sms using REST API in flutter dart

Problem: I am trying to intercept the SMS message body and then send the message body to the database using a POST Call REST API every time I encounter an SMS. This whole interception and sending the message body should work in the background as well and that too automatically.

What I have achieved so far: I am using the telephony plugin to intercept the message body and I am able to print the message body every time I receive one at the UI level but unable to call the API and send the SMS body.

Error: Since I did not find a way to how to automatically call the API every time a new message is intercepted so I used a button to call it instead but even that did not work and it throws the error as

[error:flutter/lib/ui/ui_dart_state.cc(209)] unhandled exception: invalid argument(s) (onerror): the error handler of future.catcherror must return a value of the future's type

Also, I did not manage how do I intercept the SMS message body in the background.

To better understand this error I will be attaching a few of my code snippets:

API usage function:

String body = "";
  DateTime currentPhoneDate = DateTime.now();
  final telephony = Telephony.instance;
  interceptMessage() {
    final messaging = ApiService();
    messaging.interceptedMessage({
      "id": 50,
      "body": "$body",
      "senderName": "IDK",
      "timeStamp": "2021-10-02 12:00:55"
    })
      ..then((value) {
        if (value.status == "Success") {
          print('Message Intercepted');
        } else {
          print('Somethig went wrong');
        }
      });
  }

API Class:

Future<SmsResponse> interceptedMessage(dynamic param) async {
    var client = http.Client();

    String? token = await storage.readSecureToken('key');
    if (token == null) {
      throw Exception("No token stored in storage");
    }
    try {
      var response = await client
          .post(
            Uri.https("baseURL", "endpoint"),
            headers: <String, String>{
              'Authorization': 'Token $token',
            },
            body: param,
          )
          .timeout(Duration(seconds: TIME_CONST))
          .catchError(handleError);
      if (response.statusCode == 200) {
        print('Response Body: ${response.body}');
        final data = await jsonDecode(response.body);
        return SmsResponse.fromJson(data);
      } else if (response.statusCode == 401) {
        print("Unauthorized Request");
        return param;
      } else {
        print("Bad Input");
        return param;
      }
    } catch(e){
      print(e);
   }
  }

Telephony Plugin Usage:

 @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  onMessage(
    SmsMessage message,
  ) async {
    setState(() {
      body = message.body ?? "Error reading message body.";
      print("$body");
    });
  }

  onSendStatus(SendStatus status) {
    setState(() {
      body = status == SendStatus.SENT ? "sent" : "delivered";
    });
  }

  Future<void> initPlatformState() async {
    final bool? result = await telephony.requestPhoneAndSmsPermissions;

    if (result != null && result) {
      telephony.listenIncomingSms(
        onNewMessage: onMessage,
        onBackgroundMessage: onBackgroundMessage,
        listenInBackground: true,
      );
    }
    if (!mounted) return;
  }

Handle Error Function

void handleError(error) {
    //hideLoading();
    if (error is BadRequestException) {
      var message = error.message;
      DialogHelper.showErroDialog(description: message);
    } else if (error is FetchDataException) {
      var message = error.message;
      DialogHelper.showErroDialog(description: message);
    } else if (error is ApiNotRespondingException) {
      DialogHelper.showErroDialog(
          description: 'Oops! It took longer to respond.');
    } else if (error is SocketException) {
      print(
          error); //Have to remove this part this is already being handled at the service level
    } else {
      print("All OK");
    }
  }

UI Level:

Text("$body");
like image 732
Pratyay Sinha Avatar asked Oct 27 '22 11:10

Pratyay Sinha


1 Answers

Look at [error:flutter/lib/ui/ui_dart_state.cc(209)] unhandled exception: invalid argument(s) (onerror): the error handler of future.catcherror must return a value of the future's type.

It says catcherror handler. So let us look at your handleError function.

As you can see, handleError does not return anything. In other words, it returns null (automatically).

On the other hand, looking at your var response = await client.post().catchError(), your client.post() must return some types such as Response or something like that. So that is what the error says.

Good solution: Spend an hour learning async/await in Flutter! You will find it very very helpful later on. Then refactor your code using await ... and catch and no catchError() is needed.

Workaround (not that good) solution: throw e; inside your handleError.

like image 132
ch271828n Avatar answered Nov 15 '22 06:11

ch271828n