使用期货时已经发送了Dart AppEngine标题

时间:2016-04-16 23:51:59

标签: google-app-engine dart

我正在使用AppEngine并在Dart中编写了一个服务器应用程序。由于gcloud API几乎都在使用Futures,我也会使用它们。但问题是,一旦我开始使用Futures,就会抛出BadStateException。请参阅以下两个示例。

工作服务器

  runAppEngine((HttpRequest request) {
    request.response
      ..writeln('Hello world')
      ..statusCode = HttpStatus.OK
      ..close();
  }, port: port);

输出:

  

Hello world

无效服务器:已发送标头

Future _asyncTask(HttpRequest request) {
  return new Future(() {
    request.response
      ..writeln('Hello world')
      ..statusCode = HttpStatus.OK; // causes BadStateException
  }).catchError((e) {
    request.response.writeln(e.toString());
  }).whenComplete(() {
    request.response.close();
  });
}


  runAppEngine((HttpRequest request) {
    return _asyncTask(request);
  }, port: port);

输出:

  

Hello world
状态错误:HTTP标头已经发送。


我想使用期货但由于某些原因,我无法摆脱BadStateException。有人能指出我做错了吗?

1 个答案:

答案 0 :(得分:1)

好吧,好像我发现了这个bug。我一整天都在寻找解决这个问题的方法,现在我问这里,五分钟后我就找到了问题。

无论如何,我希望这个答案可以帮助人们解决同样的问题。

问题在于写入响应时,会隐式设置标头。因此,一旦你致电writeln(String),你就不能再设置任何标题了。

第一个服务器代码中没有记录错误的原因是,没有记录错误的逻辑,但它与第二个错误一样错误。

这是正确的做法:

Future _asyncTask(HttpRequest request) {
  return new Future(() {
    request.response
      ..statusCode = HttpStatus.OK
      ..writeln('Hello world');
  }).catchError((e) {
    request.response.writeln(e.toString());
  }).whenComplete(() {
    request.response.close();
  });
}


  runAppEngine((HttpRequest request) {
    return _asyncTask(request);
  }, port: port);

如您所见,首先发送标头可以解决问题。