Once the response status is sent on the wire, it cannot be changed. So if you sent a 200 OK
response, you cannot change your mind afterwards. As you found, this presents a problem in case of errors that occur mid response.
As far as I know, the only think you can do is to send a chunked response. See section 3.6.1 of RFC 2616:
The chunked encoding modifies the body of a message in order to
transfer it as a series of chunks, each with its own size indicator,
followed by an OPTIONAL trailer containing entity-header fields. This
allows dynamically produced content to be transferred along with the
information necessary for the recipient to verify that it has received
the full message.
The purpose of this trailer is to give information about the entity body that cannot be calculated before the entity body is sent. However, section 7.1 allows any header to be included in this trailer:
The extension-header mechanism allows additional entity-header fields
to be defined without changing the protocol, but these fields cannot
be assumed to be recognizable by the recipient. Unrecognized header
fields SHOULD be ignored by the recipient and MUST be forwarded by
transparent proxies.
So while you can signal that an error has occurred mid response, it must be conventioned between the two parts how this is signaled. You cannot, in general, use any method you can assume the client will understand as signaling an error condition.
Ending the connection prematurely in a message with a Content-length
header is an option, but one that is explicitly forbidden:
When a Content-Length is given in a message where a message-body is
allowed, its field value MUST exactly match the number of OCTETs in
the message-body. HTTP/1.1 user agents MUST notify the user when an
invalid length is received and detected.
That said, while the server must not send a message shorter than he advertises, the client must check for this error condition and reported as such (and proxies may even cache this partial response).