2016-04-16 7 views
2

Ich benutze AppEngine und schrieb eine Server-Anwendung in Dart. Da die gcloud-API Futures für fast alles verwendet, nutze ich sie auch. Das Problem jedoch, sobald ich anfange, Futures zu verwenden, wird BadStateException geworfen. Siehe die beiden folgenden Beispiele.Dart AppEngine Header bereits gesendet, wenn Futures

Arbeits Server

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

Ausgang:

Hallo Welt



Problem Server: Header gesendet bereits

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); 

Ausgang:

Hallo Welt
Bad Zustand: HTTP-Header wurden bereits gesendet.



würde Ich mag Futures verwenden, aber aus irgendwelchen Gründen, ich kann einfach nicht loswerden der BadStateException bekommen. Kann mir jemand auf das hinweisen, was ich falsch mache?

Antwort

1

Oh gut, scheint wie ich den Fehler gefunden. Ich suchte den ganzen Tag nach einer Lösung für dieses Problem und jetzt, wo ich hier frage, finde ich das Problem fünf Minuten später.

Wie auch immer, ich hoffe, diese Antwort hilft Menschen mit dem gleichen Problem.

Das Problem ist, dass beim Schreiben in die Antwort Header implizit gesetzt werden. Wenn Sie also writeln(String) anrufen, können Sie danach keine Header mehr setzen.

Der Grund, dass kein Fehler im ersten Servercode protokolliert wurde, ist, dass es einfach keine Logik gibt, Fehler zu protokollieren, aber es ist so falsch wie die zweite.

Hier ist der richtige Weg, es zu tun:

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); 

Wie Sie sehen können, das Problem durch Senden des Header zuerst festgelegt ist.