JsonServiceClient response filter problem ignores 400 & 401 responses

Hi, I use "servicestack-client": "0.0.19" in my code with simple implementation

import { JsonServiceClient } from 'servicestack-client';
import * as state from '../store/state'
import * as store from '../store/index'
import * as mutations from '../store/mutation-types'

const client = new JsonServiceClient(state.default.serverURI)

client.requestFilter = httpReq => {
    console.info(httpReq)
    store.default.commit(mutations.API_CALL_STARTED)
};

client.responseFilter = httpRes => {
    console.info(httpRes) // filter is not executed on 400 & 401 status
    store.default.commit(mutations.API_CALL_COMPLETED)
};
export default client

Below is API call

export const LOGIN = ({commit, state}, data) => {
    var req = new dtos.Authenticate();
    req.password = data.password
    req.userName = data.userName
    JsonServiceClient.post(req)
    .then(r => { 
        commit(types.API_CALL_COMPLETED)
    })
    .catch(e => {
        commit(types.API_CALL_COMPLETED, e)
    })
}

the request filter works fine but the response filter is not executed when my api returns 400 & 401 status code. What can be the issue?

You’ll need to add:

req.provider = “credentials”;

This doesn’t resolve problem with JsonServiceClient. The responseFilter is not executed.

From source code here https://github.com/ServiceStack/servicestack-client/blob/master/src/index.ts#L331 it looks like responseFilter is not executed in case of 4XX & 5XX stats codes?

Right the Response Filter is only executed on successful responses.

Do you plan to introduce some kind of errorFilter to JsonServiceClient?

Wasn’t planning on it till you asked :slight_smile: but I’ve added an exceptionFilter in this commit.

This change is available from v0.0.20 which is now available on npm.

1 Like

Thanks :slight_smile: I was testing that change and response is not properly deserialized

{"responseStatus":{"errorCode":"Unauthorized","message":"Invalid UserName or Password","errors":[]}}

The err.responseStatus.message is empty (and errorCode also

client.exceptionFilter = (res, err) => {
    console.info(err.responseStatus.message); // empty but should be 
   ///Invalid UserName or Password     
}

I haven’t been able to reproduce this after adding some failed auth + exception filter tests.

I need to repro this somehow, can you provide the full HTTP Request/Response Headers for this request which fails, also is your API public?

I was thinking that it might be because of some webpack misconfiguration?

This is the request

POST http://localhost/my.api/json/reply/Authenticate HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 76
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.54 Safari/537.36
content-type: text/plain;charset=UTF-8
Accept: */*
Referer: http://localhost:8080/weded
Accept-Encoding: gzip, deflate, br
Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4
Cookie: _ga=GA1.1.2079302235.1473015720; X-UAId=3; ss-id=Xbp1r1sesXKiTOOR9Q0X; ss-pid=OJ9TThJ7WbppwBAQifVh; ss-opt=temp

{"password":"Password","userName":"ewrverv@com.pl","provider":"credentials"}

This is the response

HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: application/json; charset=utf-8
Vary: Accept
Server: Microsoft-IIS/8.5
X-Powered-By: ServiceStack/4.56 Win32NT/.NET
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
X-AspNet-Version: 4.0.30319
Set-Cookie: ss-id=ZAgXfkCGlUDjG0p1XGkw; path=/; HttpOnly
Set-Cookie: ss-pid=AHSNEoOuMgdvMy2MvGjp; expires=Thu, 19-Feb-2037 07:20:07 GMT; path=/; HttpOnly
Set-Cookie: ss-opt=temp; expires=Thu, 19-Feb-2037 07:20:07 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Sun, 19 Feb 2017 07:20:07 GMT
Content-Length: 913

{"responseStatus":{"errorCode":"Unauthorized","message":"Invalid UserName or Password","stackTrace":"[Authenticate: 2/19/2017 7:20:07 AM]:\n[REQUEST: {provider:credentials,userName:ewrverv@com.pl,password:Password}]\nServiceStack.HttpError: Invalid UserName or Password\r\n   at ServiceStack.Auth.CredentialsAuthProvider.Authenticate(IServiceBase authService, IAuthSession session, String userName, String password, String referrerUrl)\r\n   at ServiceStack.Auth.CredentialsAuthProvider.Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)\r\n   at ServiceStack.Auth.AuthenticateService.Authenticate(Authenticate request, String provider, IAuthSession session, IAuthProvider oAuthConfig)\r\n   at ServiceStack.Auth.AuthenticateService.Post(Authenticate request)\r\n   at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)","errors":[]}}

From some reason I am unable to get response data also for 200 response

ok the problem was setting client.mode to “no-cors”. After comment this
works fine

const client = new JsonServiceClient('http://localhost/my.api')
//client.mode = "no-cors"

Any change to the default configuration is definitely something you should’ve included with your issue, been spending the morning trying to repro this and didn’t stand any chance without knowing this.

The behavior of no-cors says it disables JavaScript from reading the Response.

1 Like

sorry @mythz for this missing information, Fetch api is new for me and I was trying a lot of different settings when I had problem why responseFilter is not handling 400/401 responses. I hope this topic will help others who starting using JsonServiceClient.