Hi,
I’m using the ServiceStack Dart client (3.0.2) in a Flutter app and I think I’ve found a bug (or maybe I’m misunderstanding something).
Here’s what happens:
- I have a request DTO that implements IReturnVoid.
- On the client, I’m sending it with:
await client.apiVoid(req);
- When the server returns an error, everything works as expected – I get a proper ApiException.
- But when the server executes successfully and returns no response body, the Dart app crashes.
 
            
              
              
              
            
           
          
            
            
              I have found a quick fix to return EmptyResponse when response is null in the sendRequest method in client.dart.
client.dart:
 Future<T> sendRequest<T>(SendContext info) async {
    int statusCode = -1;
    HttpClientResponse res;
    try {
      var req = await createRequest(info);
      if (urlFilter != null) {
        urlFilter!(req.uri.toString());
      }
      res = await req.close();
      statusCode = res.statusCode;
    } on Exception catch (e) {
      Log.debug("sendRequest() createRequest: $e");
      return await handleError(null, e);
    }
    try {
      var response = await createResponse(res, info);
      return response ?? EmptyResponse();  // <--- THIS LINE IS CHANGED
    } on Exception catch (e) {
      var debug = Log.isDebugEnabled();
      if (debug) Log.debug("sendRequest(): statusCode:$statusCode, $e");
      if (statusCode == 401) {
        var hasRefreshTokenCookie = cookies!.any((x) => x.name == "ss-reftok");
        if (refreshToken != null || useTokenCookie || hasRefreshTokenCookie) {
          var jwtRequest = GetAccessToken(refreshToken: this.refreshToken);
          var url = refreshTokenUri ?? createUrlFromDto("POST", jwtRequest);
          var jwtInfo = SendContext(
              method: "POST", request: jwtRequest, args: null, url: url);
          try {
            var jwtReq = await createRequest(jwtInfo);
            var jwtRes = await jwtReq.close();
            var jwtResponse =
                await createResponse<GetAccessTokenResponse>(jwtRes, jwtInfo);
            bearerToken = jwtResponse!.accessToken;
            if (debug) Log.debug("sendRequest(): bearerToken refreshed");
            return await _resendRequest<T>(info);
          } on Exception catch (jwtEx) {
            if (debug) Log.debug("sendRequest(): jwtEx: $jwtEx");
            return await handleError(
                res, jwtEx, WebServiceExceptionType.RefreshTokenException);
          }
        }
        if (onAuthenticationRequired != null) {
          await onAuthenticationRequired!();
          return await _resendRequest<T>(info);
        }
      }
      return await handleError(res, e);
    }
  }