ExecTypedFilters throws exceptions with NULL return types

In our API we have many “utility/action” endpoints that trigger a server-side action but that don’t necessarily have a return value. Many are return void, or return int.

I noticed that if I use GlobalTypedResponseFilters, calls to services that return void throw exceptions. Upon inspection, I see that in ExecTypedFilters there is no null check on dto.

public virtual void ExecTypedFilters(...){
    ...
    var dtoType = dto.GetType();
}

The exception at this stage of the pipeline means that the end response doesn’t go through the success channel. Breaks a few things.

Suggestions? (other than scanning all dlls to ensure no return voids)

The response of a Service should never return a value type.

You can try ending the Response: IResponse.End()

But if it returns null, wouldn’t dto.GetType() also fail? Say you fetch person id=5 and it doesn’t exist, a return null is easily adapted in angular. You would prefer instead to return http error code?

Not sure where the IResponse.End() would go. It can’t go in the filter itself because the exception is thrown higher up in ExecTypedFilters. Would it be that “wrong” to bound-check in the Exec part? Or do you mean adding End() in the method that would normally return void?

IResponse is the Response Context, it’s never null.

You’d want to call it immediately after the Service is executed in the Response pipeline. e.g. you can try calling it by overriding AppHost.OnAfterExecute(), e.g:

public override object OnAfterExecute(IRequest req, object requestDto, object response)
{
    if (response == null) {
        req.Response.End();
        return null;
    }
    return base.OnAfterExecute(req, requestDto, response);
}

I must be missing something … but the AppHost (and parent classes) do not define an OnAfterExecute. The service runner does; however, the signature of the service runner OnAfterExecute does not include the DTO.

thanks!

I am trying this in a ServiceRunner … initial test seems ok:

if (response == null)
{
    response = new object();
    requestContext.Response.End();
    return base.OnAfterExecute(requestContext, response);
}

It’s defined in ServiceStackHost which is the base class for all AppHosts: ServiceStack/src/ServiceStack/ServiceStackHost.Runtime.cs at master · ServiceStack/ServiceStack · GitHub

Ahh, I see that it was added in early March and thus not in my version (4.0.36) - will look to update to latest.