Lukasz
Lukasz

Reputation: 2317

Uncaught Error: Bad state: Header already sent

I couldn't find anything relating to this error and dart, hence the question.

What might cause this error in a simple server application.

import 'package:auctionprojectServer/auctionprojectServer.dart' as auctionprojectServer;
import 'dart:io';
import 'package:http_server/http_server.dart' show VirtualDirectory;

VirtualDirectory virDir;

main() {
    initVirDir();
    runServer();
}


/**
 *  Code for virtual directory
 */
initVirDir() {
  virDir = new VirtualDirectory(r"..\auctionProject\web")   // change to build\web after 2js
    ..allowDirectoryListing = true
    ..directoryHandler = directoryHandler;
}

directoryHandler(dir, request) {
  var indexUri = new Uri.file(dir.path).resolve('auctionproject.html');
  virDir.serveFile(new File(indexUri.toFilePath()), request);  
}

/* end of virtual directory related code */


/**
 *  Code to handle Http Requests
 */
runServer() async {
  var server = await HttpServer.bind('127.0.0.1', 8080).catchError((e) => print(e));
  await for (HttpRequest request in server) {
    handleAnyRequest(request);
    request.response.close();
  }
}

handleAnyRequest(HttpRequest request) {
  switch (request.method) {
    case 'GET':
      handleGetRequest(request);
      break;
    case 'POST':
      handlePostRequest(request);
      break;
    default: defaultRequestHandler(request);
  }
}

handleGetRequest(HttpRequest req) {
  print('got GET request');
  virDir.serveRequest(req).catchError((e)=> print('annoying error'));  // <<<
}

handlePostRequest(HttpRequest req) {
  print('got POST request');
}

// place for other request types

defaultRequestHandler(HttpRequest req){
  print('some unhandled request!!!\n');
}

/* end of code handling Http Requests */

After commenting out the code marked with // <<< the error disappears. On the other hand annoying error is never printed so I am not sure where the problem originates from.

The console output is shown below.

got GET request
got GET request
Unhandled exception:
Uncaught Error: Bad state: Header already sent
Stack Trace:
#0      _HttpResponse.statusCode= (dart:io/http_impl.dart:523)
#1      VirtualDirectory.serveFile.<anonymous closure> (package:http_server/src/virtual_directory.dart:287:16)
#2      _RootZone.runUnary (dart:async/zone.dart:1155)
#3      _Future._propagateToListeners.handleError (dart:async/future_impl.dart:515)
#4      _Future._propagateToListeners (dart:async/future_impl.dart:570)
#5      _Future._completeWithValue (dart:async/future_impl.dart:358)
#6      _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:412)
#7      _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#8      _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#9      _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
#10     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:143)

#0      _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:886)
#1      _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#2      _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#3      _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
#4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:143)

Upvotes: 1

Views: 952

Answers (2)

Rafael Bartz
Rafael Bartz

Reputation: 328

I faced this error, and in my case I was changing response status code after write something to response.

request.response.write("My response JSON");
request.response.statusCode = 200; 

So, I had to change to:

request.response.statusCode = 200; 
request.response.write("My response JSON");
 

Requests response status code are 200 by default, so if there is not an error in the request, you don't need to explicitly inform status 200.

Upvotes: 1

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657248

I didn't check but I assume vdir.serveRequest() is async.

You need to await this call

await handleAnyRequest(request);

and ensure that the future returned by vdir.serveRequest is returned so it can be awaited. Otherwise request.response.close(); is called before vdir.serveRequest() is completed, thus the error.

Upvotes: 2

Related Questions