Get CustomErrorMessage by http request using ky library - node.js

I am using React and Express to create a web application.
However, the response to a request using the ky library will contain a default message.
How do I get a custom message?
By the way, this works on Postman & axios library.
//Custom Error
class HttpException extends Error {
status: number;
message: string;
constructor(status: number, message: string) {
super(message);
this.status = status;
this.message = message;
}
}
export default HttpException;
//Express
import HttpException from '../exceptions/HttpException';
if (!Object.keys(result).length) throw new HttpException(404, "User does not exist")
//Express error handling middleware
export const errorMiddleware = (err: HttpException, req: express.Request, res: express.Response, next: express.NextFunction) =>{
const status = err.status || 500;
const message = err.message || 'Something went wrong';
res
.status(status)
.send({
status,
message,
})
}
//React
import ky from 'ky'
const customKy = ky.create({
prefixUrl: process.env.NEXT_PUBLIC_API_HOST,
credentials: "include",
headers: { 'Content-Type': 'application/json' },
});
try {
const result: any = await customKy.post("path", { json: data }).json()
} catch (err: any) {
console.log(err.response.status)
console.log(err.response.message)
}
//result console
login.tsx:28 404
login.tsx:29 undefined

Related

Custom error response not working in nodejs written in typescript

I have a custom general error response and it will run when execute return next(error), but it's not working , it threw an error to the console. Please help me and give me an explanation for this.
useErrorHandler.ts: This is my custom error response extending Error
import { Request, Response } from 'express';
export class ErrorResponse extends Error {
public statusCode: number;
constructor(message: string, statusCode: number) {
super(message);
this.statusCode = statusCode;
}
}
const handleError = (err: any, req: Request, res: Response) => {
res.status(err.statusCode || 500).json({
success: false,
error: err.message || 'Internal Server Error',
});
};
export default handleError;
category.controller.ts: This is my controller, i tried to give an error
import { NextFunction, Request, Response } from 'express';
import { createCategory } from '../services/category.service';
import { ErrorResponse } from '../middlewares/error';
export const handleCreateCategory = async (
req: Request,
res: Response,
next: NextFunction
) => {
// const category = await createCategory(req.body);
// return res.status(200).send(category);
return next(new ErrorResponse('cccca 3000', 401));
};
app.ts: this is my main file, it contains routes, headers, middlewares, etc.
import express, { Express, Response, Request } from 'express';
import {
authRouter,
productRouter,
categoryRouter,
cartRouter,
} from './routes';
import { useErrorHandler } from './middlewares';
class App {
public express: Express;
private readonly ENDPOINT: string;
constructor() {
this.express = express();
this.ENDPOINT = '/api/v1';
this.setHeaders();
this.setMiddlewares();
this.mountRoutes();
}
private setHeaders(): void {}
private setMiddlewares(): void {
this.express.use(express.json());
this.express.use(express.urlencoded());
}
private mountRoutes(): void {
this.express.use(`${this.ENDPOINT}/auth`, authRouter);
this.express.use(`${this.ENDPOINT}/product`, productRouter);
this.express.use(`${this.ENDPOINT}/category`, categoryRouter);
this.express.use(`${this.ENDPOINT}/cart`, cartRouter);
//handle err
this.express.use(useErrorHandler);
}
}
export default new App().express;
Using Postman to test the error response
Your error-handler middleware should always have 4 arguments. That's how Express knows it is an error-handler method.
If you write your handleError function like the code below it will work.
const handleError = (err: any, req: Request, res: Response, next: NextFunction) => {
...
};
You can read more about it in the official Express Docs.
https://expressjs.com/en/guide/error-handling.html
Refer to the section Writing error handlers.

in typescript env, I create HttpException that derive class of Error, use it at my express error handler

why it can use without new HttpException() then trown a error
I saw this method elsewhere,and it is work
Here is HttpException
class HttpException extends Error{
constructor(public status: number,public message: string){
super(message);
this.status=status;
this.message=message;
}
}
export default HttpException;
Here is error handler
const errorMiddleware = (error: HttpException, _request: Request, response: Response, next: NextFunction) => {
const status = error.status || 500;
const message = error.message || ' something wrong';
response
.status(status)
.send({
status,
message
});
logger.error(error.name);
logger.error(error.message);
logger.error(error.stack);
next(error);
};
user in app.ts
// ...some routers
app.use(errorMiddleware)
api error in postman
{
"status": 500,
"message": "User validation failed: username: Error, expected `username` to be unique. Value: `aaa111`"
}

how can I implement the exception filters in Nest in node?

I need something like this in the vanilla node js, can someone guide me through?
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '#nestjs/common';
import { Request, Response } from 'express';
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
you can write a filter middleware/interceptor like the following to handle custom errors, however, you will have to update your current implementation to match the solution
app.use('/', filter);
app.get('/',(req, res)=> {
try {
//do somethind
throw new Error('My error')
} catch(error) {
return res.json({error: error})
}
});
function filter(req, res, next) {
const Res = res.json;
res.json = function(data) {
if(data.error && data.error instanceof Error) {
data.error = data.error +': handled error';
}
Res.call(res, data);
}
next();
}

How to return exception from common error handler in nodejs

My API is in nodejs with a layered architecture. Im facing problem in returning an error from anywhere in the application. My express error handler is capturing the error but then my controller logic is also getting executed. Below is my sample code.
//accountcontroller.ts
updateAccountStatus = async (req: Request, res: Response, next: any): Promise<any> => {
let responseFromService = await AccountService.updateAccountStatus(
parseInt(req.params.accountId),
next
);
// even after the exception it comes here, after visiting the express default error code
if (responseFromService !== undefined) {
responseHandler(res, 200, responseFromService);
}
if (responseFromService.err) {
return next(responseFromService);
}
//accountService.ts
public updateAccountStatus = async (accountId: number, next: any): Promise<any> => {
let accountStatusReponse = await accountRepository.updateAccountStatus(accountId, next);
return accountStatusReponse;
};
//accountRepository.ts
public updateAccountStatus = async (accountId: any, next: any): Promise<any> => {
try {
const updateAccountStatus = await Accounts.updateOne(
{ id: accountId },
{ accountStatus: true }
);
if (updateAccountStatus) {
return updateAccountStatus;
} else {
throw new Error("Error while saving the data");
}
} catch (error) {
error.err = error.message;
error.status = 500;
return next(error);
}
};
//responseHandler is my commons file to return the responses.
responseHandler.ts
class responseHandler {
constructor() {}
statusCodeResponse = (
response: any,
message: string,
statusCode: number,
): void => {
response.statusMessage = statusMessage;
response
.status(statusCode)
.json(
response: response,
message: message
)
);
};
}
//app.js
import accountRouter from "./routes/accountroute";
var app = express();
app.use("/accounts", accountRouter);
Any suggestions on how do I make returns so that in case of an exception the control don't move back to the previous file.

How to show node js api error in Angular app

In my Node.js app I return an error like this:
app.get('/api/login', (req, res, next) => {
//...
return res.status(400).send({
isSuccess: false,
errors: ["error 1", "error 2"]
})
})
In Angular, how can I get the error?
login() {
const headers = new HttpHeaders().set('Accept', 'application/json').set('Content-Type', 'application/json');
this.http.post('http://localhost:3000/api/login', { username: 'arwels', password: '24899632' }, { headers: headers }).subscribe(response => {
// ok
}, (err) => {
console.log(err) // Bad Reqeust
});
}
When I print err in the error section, it prints Bad Reqeust. Where is the object that is sent by the server?
You can use an HttpInterceptor to capture error responses from your API.
Ref: https://angular.io/api/common/http/HttpInterceptor
Here's an Example:
export class MyHttpInterceptor implements HttpInterceptor {
constructor() {
}
intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError(async (_err: HttpErrorResponse, _caught: any) => {
switch (_err.status) {
case 401:
...
break;
case 500:
...
break;
default:
...
break;
}
return of(_err);
})
) as any;
}
}
Since you have full control over how you are returning your errors in your API, you can tailor the HttpInterceptor to work with any error object you want to create on your backend.
Unfavorable Option
If you just want the entire response so you can sniff out the statusCode, you can also just {observe: 'response'} in the HttpHeaders.
this.http.get<HttpResponse<any>>(<url>, {observe: 'response'}).pipe(
tap(resp => console.log('response', resp))
);

Resources