Typescript client not getting http response code in catch

I am using the typescript client against servicestack services,
my service does something like this:

 throw new HttpError() { StatusDescription = "Offer expired" ,StatusCode = HttpStatusCode.Gone};

my client does something like this:
.then(() => {

    }).catch((e: any) => {

      console.log(e);

exception looks like this, and I need the HTTP code in that catch callback…
{responseStatus: {…}}
responseStatus
:
errorCode
:
“InternalServerError”
errors
:
[]
message
:
“InternalServerError”
stackTrace
:
“[GetJobOfferFromShortCode: 1/12/2023 3:09:16 PM]:\n[REQUEST: {shortCode:jjdly}]\r\n\r\n”
[[Prototype]]
:
Object
[[Prototype]]
:
Object

I have:
-Removed all exception filtering
-Turned debug mode off

  • Changed the signature of method from void() to object
  • Tried other status codes like 404

Hi @kev_rm,

When you do run it in debug mode, can you see the stacktrace coming from your thrown HttpError or somewhere else? If you can share the stacktrace, this should narrow down where the response might be getting changed, either by an unhandled exception or through a filter. There are quite a few places responses could be getting changed, that hopefully the stacktrace will point to.

The fact that changes to your service returning void and status code doesn’t make a difference, it’s likely it is an error happening somewhere before the request is finished and/or one of the above handling the exception and modifying the response. If you paste your stacktrace here, it should be clearer.

Another thing to check would be to try the same service with another client like a C# client to see if you get the same result or something different.

The browser sees the error code. Its the same error code that I’m throwing. I don’t think this is the case above - I actually think the typescript client is missing / obfuscating the http response itself in a way that’s not good. - you shouldn’t need to inspect an exception to get the error code because they are two different things - is there a way to get deeper into the response than the catch resolve?

Edit: Said another way - I don’t care whats happening on the server - regardless i do want to get the http status code in the typescript client. how do I do that?

@kev_rm, thanks for clarifying that.

When you say “The browser sees the error code” is that from the same TypeScript client making the same call or replicating the call directly in the browser? The TypeScript client by default doesn’t change the response code by default. Without a reproduction of the issue, it is hard for me to point to the exact problem.

It might depend what version you are using, can you confirm what version of the @servicestack/client you are using? The newer API will return an object that contains the error and the result so the syntax would be:

const api = client.api(new Hello({ name }))
if (api.failed) {
    console.log(`Greeting failed! ${api.errorCode}: ${api.errorMessage}`);
    return;
}

console.log(`API Says: ${api.response.result}`) //api.succeeded

Rather than using a try/catch, if you can look at the failed. See the client tests for more examples.

Alternatively you can use responseFilter to access the fetch API response.

Let us know if you are still seeing an issue, so I can help hunt down a bug if there is one.

I think I must be doing something wrong - I don’t think it is intended to be hard to get the http status code back from an api call - in straight js or ts the resource coming back has a statusCode (2xx, 4xx, etc) - We were using 1.2.1. We can’t use an (undocumented?) “.api” method, we need the verbs and the promises. Using a response filter to try to inject the http status code back into the dtos seems really kinda lame, no?

To try to reduce misunderstandings here, I’ve created a reproduction of what I think should be at least close to what you have. A Typescript (node) client that uses a ServiceStack backend (in the server directory) that returns your HttpError and asserts the error code (status code 410), using @servicestack/client@1.2.1.

While the servicestack client here doesn’t return the raw fetch response object, this the responseStatus contains the error message that the server is returning, and the HTTP status code specified (410). The underlying HTTP response headers are the same, returning a 410, and the custom text “Offer expired” is in the response status message.

Server code:

public object Any(HelloError request)
{
    if (request.Name == "Foo")
        return new HelloErrorResponse { Result = $"Hello, {request.Name}!" };

    return new HttpError()
    {
        StatusDescription = "Offer expired", 
        StatusCode = HttpStatusCode.Gone
    };
}

Client code:

client.post(new HelloError()).then((result) => {
    console.log(result)
}).catch((e) => {
    assert(e.responseStatus.errorCode === '410')
    assert(e.responseStatus.message === 'Offer expired')
})

Let me know if I’ve got it correct, and if you are able to run the example with the client passing the assert statements or not.

responseStatus was not part of the exception object in 1.2.1 of the client (or perhaps in that combination of client version and my version of servicestack server…)
upgrading the typescript client has resolved the issue.

1 Like

Glad the issue was sorted, let us know if you have other issues with the TypeScript client.