runServer method

Future<CommandResultDto> runServer(
  1. String serverId,
  2. String? hostType, {
  3. int timeoutSeconds = -1,
  4. List<String>? extraCmds,
})

POST /tools/create

Implementation

Future<CommandResultDto> runServer(
  String serverId,
  String? hostType, {
  int timeoutSeconds = -1,
  List<String>? extraCmds,
}) async {
  final Map<String, dynamic> queryParameters = {
    'serverId': serverId,
    if (hostType != null && hostType.isNotEmpty) 'hostType': hostType,
    if (timeoutSeconds >= 0) 'timeout': '$timeoutSeconds',
  };
  final Map<String, dynamic>? requestBody =
      extraCmds != null && extraCmds.isNotEmpty ? {'args': extraCmds} : null;
  final completer = Completer<CommandResultDto>();
  StreamSubscription<String>? subscription;
  void completeWithError(Object error, [StackTrace? stack]) {
    if (!completer.isCompleted) {
      completer.completeError(error, stack ?? StackTrace.current);
    }
  }

  try {
    Stream<String> sseStream = await toolSse.request(
      '/create',
      queryParameters: queryParameters,
      requestBody: requestBody,
    );
    void onEvent(String event, Map<String, dynamic> data) {
      if (event == EventType.DATA && !completer.isCompleted) {
        final result = CommandResultDto.fromJson(data);
        completer.complete(result);
        subscription?.cancel();
      } else if (event == EventType.ERROR && !completer.isCompleted) {
        final result = CommandResultDto.fromJson(data);
        completeWithError(CommandException('runServer', result.error ?? ''));
        subscription?.cancel();
      }
    }

    subscription = sseStream.listen(
      (chunk) => SseClient.parse(chunk, onEvent),
      onError: completeWithError,
      cancelOnError: true,
      onDone: () {
        if (!completer.isCompleted) {
          completeWithError(
            CommandException(
              'runServer',
              'Connection closed before response',
            ),
          );
        }
      },
    );
  } catch (error, stackTrace) {
    completeWithError(error, stackTrace);
  }

  try {
    return await completer.future;
  } catch (error, stackTrace) {
    final normalized = _normalizeError(error);
    if (identical(normalized, error)) rethrow;
    Error.throwWithStackTrace(normalized, stackTrace);
  }
}