flutterdart

The body might complete normally, causing 'null' to be returned, but the return type, 'FutureOr<Response<dynamic>>'


Given the following

  Future<void> clipsAdd(int questionId) async {
    await _authenticatedRequest((options) async {
      final String uri = "$domain/clips/add?questionId=$questionId";
      final response = await dio.post(uri, options: options);

      if (response.statusCode != 200) {
        throw Exception('Failed to process request: ${response.statusCode}');
      }
    });
  }

I get the the error message

The body might complete normally, causing 'null' to be returned, but the return type, 
'FutureOr<Response<dynamic>>', is a potentially non-nullable type.
Try adding either a return or a throw statement at the end.

How can I fix this one?


Solution

  • The error occurs because the Dart analyzer expects your function to return a value of type FutureOr<Response>, but there’s no explicit return statement in your function. When a non-void function completes without returning a value, Dart assumes null is returned, which contradicts the return type.

    Solution 1: Return the Response

    If your intention is to return the response, update your code to explicitly return it. Here's the corrected version:

    Future<Response<dynamic>> clipsAdd(int questionId) async {
      return await _authenticatedRequest((options) async {
        final String uri = "$domain/clips/add?questionId=$questionId";
        final response = await dio.post(uri, options: options);
    
        if (response.statusCode != 200) {
          throw Exception('Failed to process request: ${response.statusCode}');
        }
    
        return response; // Explicitly return the response
      });
    }
    

    Solution 2: Change the Return Type to Future

    If you don’t need to return the response, update the function’s return type to Future and ensure it matches the implementation:

    Future<void> clipsAdd(int questionId) async {
      await _authenticatedRequest((options) async {
        final String uri = "$domain/clips/add?questionId=$questionId";
        final response = await dio.post(uri, options: options);
    
        if (response.statusCode != 200) {
          throw Exception('Failed to process request: ${response.statusCode}');
        }
    
        // No need to return anything since the return type is void
      });
    }
    

    Additional Tip: Storing the Response in an External Variable

    If you want to store the response in a variable outside the function, declare a variable at a higher scope and update it within the function:

    Response<dynamic>? lastResponse; // Declare outside the function
    
    Future<void> clipsAdd(int questionId) async {
      await _authenticatedRequest((options) async {
        final String uri = "$domain/clips/add?questionId=$questionId";
        final response = await dio.post(uri, options: options);
    
        if (response.statusCode != 200) {
          throw Exception('Failed to process request: ${response.statusCode}');
        }
    
        lastResponse = response; // Store the response in an external variable
      });
    }
    

    Choose the solution that best fits your needs:

    Best Practice Recommendation

    To follow best practices:

    1. If you need the response only within the function, return response.data instead of the entire response. This simplifies the function and makes it more reusable:
    Future<dynamic> clipsAdd(int questionId) async {
      return await _authenticatedRequest((options) async {
        final String uri = "$domain/clips/add?questionId=$questionId";
        final response = await dio.post(uri, options: options);
    
        if (response.statusCode != 200) {
          throw Exception('Failed to process request: ${response.statusCode}');
        }
    
        return response.data; // Return the response data
      });
    }
    
    1. If you need the response globally, store response.data in a well-named external variable, as shown earlier. Avoid storing the entire Response object unless it's necessary.

    By focusing on returning or storing response.data, you ensure the function only exposes what is actually needed, improving code readability and maintainability.