readResponse method

  1. @override
Future<WorkResponse> readResponse()
override

Note: This will attempts to recover from invalid proto messages by parsing them as strings. This is a common error case for workers (they print a message to stdout on accident). This isn't perfect however as it only happens if the parsing throws, you can still hang indefinitely if the MessageGrouper doesn't find what it thinks is the end of a proto message.

Implementation

@override
Future<WorkResponse> readResponse() async {
  var buffer = await _messageGrouper.next;
  if (buffer == null) {
    return WorkResponse(
      exitCode: EXIT_CODE_BROKEN_PIPE,
      output: 'Connection to worker closed',
    );
  }

  WorkResponse response;
  try {
    response = WorkResponse.fromBuffer(buffer);
  } catch (_) {
    try {
      // Try parsing the message as a string and set that as the output.
      var output = utf8.decode(buffer);
      var response = WorkResponse(
        exitCode: EXIT_CODE_ERROR,
        output: 'Worker sent an invalid response:\n$output',
      );
      return response;
    } catch (_) {
      // Fall back to original exception and rethrow if we fail to parse as
      // a string.
    }
    rethrow;
  }
  return response;
}