Hi,
now ServiceExceptionHandlers has been called before OnEndRequest, but still I’m not able to distinguish between exception occured within the service method or outside such as serialization during the output.
An other issue with this new changes is the retuned object from the ServiceExceptionHandler will not be written in the output, but the previous one will be (the one created before the serialization error raised)
the override you proposed has 2 issue: a minor one
HostContext.CompleteRequest(req);
is internal. So I tried to call it via reflection
the major one is the output contains “2 outputs”: the original one before the serialization error occurs + the custom one I create through the custom uncaughtException handler. In short the response buffer has not been clean it out.My uncaughtExceptionHandler implementation down below (based on \src\ServiceStack\HttpResponseExtensionsInternal.cs)
private void uncaughtExceptionHandler(IRequest req, IResponse res, string operationName, Exception ex)
{
//my output customization
var errorDto = createResponseStatusForUncaughtException(operationName, ex);
var httpReq = req;
var httpRes = res;
var contentType = httpReq.ResponseContentType;
var statusCode = (int) HttpStatusCode.InternalServerError;
if (httpRes.ContentType == null || httpRes.ContentType == MimeTypes.Html)
{
httpRes.ContentType = contentType;
}
if (HostContext.Config.AppendUtf8CharsetOnContentTypes.Contains(contentType))
{
httpRes.ContentType += ContentFormat.Utf8Suffix;
}
//TODO VERIFY IF StatusDescription EVER USED in the response to the client
if (httpRes.StatusDescription == null || httpRes.StatusDescription == "OK")
{
string statusDescription = (((dynamic) errorDto).Message).ToString();
// if string is longer than 512 .net raises an exception
httpRes.StatusDescription = statusDescription.Truncate(509) + "...";
}
httpRes.StatusCode = statusCode;
ResponseSerializerDelegate serializer = null;
if (contentType == "application/soap+xml")
{
// custom serializer to avoid an exception due to missing SoapMessage within the request in case of not-serializable input
serializer = SerializeSoap12ToStream;
}
else
{
serializer = HostContext.ContentTypes.GetResponseSerializer(contentType);
}
if (serializer != null)
{
serializer(httpReq, errorDto, httpRes);
}
httpRes.EndHttpHandlerRequest(skipHeaders: true);
}