Я пытаюсь сделать запрос axios внутри array.map, для каждого элемента карты мне нужно сделать запрос axios и сохранить некоторую информацию ответа. Когда я использую свою логику кода, все ошибки, обрабатываемые в моем блоке catch, не могут вызвать исключение HttpException внутри моего блока catch, поскольку он не отправляет мою ошибку обратно в мой фильтрnesjs.
Я использую перехватчик axios в файле main.ts, ошибка переходит к моему перехватчику в main.ts, и мой код прерывается.
Пример кода службы и результат (почтальон ничего не получает)
async fetchData() {
try {
const numbers = [ 1 , 2 , 3 ,4 , 5, 6]
const mapReturn = numbers.map( async (numero) => {
return
this.
httpService.
axiosRef.get('http://10.55.110.10:7076/axios/test')
})
} catch (err) {
console.info('catch console.info')
throw new HttpException('testando' , 409)
}
}
этот запрос axios возвращает только исключение httpException
над консолью кода
filter console.info
main console.info
node:internal/process/promises:289
triggerUncaughtException(err, true /* fromPromise */);
HttpException: Conflict
at <anonymous> (/var/www/html/api_testes/src/main.ts:28:13)
at process.processTicksAndRejections
(node:internal/process/task_queues:95:5)
at Axios.request
at process.processTicksAndRejections
(node:internal/process/task_queues:95:5) {
response: 'Conflict',
status: 409,
options: undefined
}
Node.js v20.11.1
перехватчик axios в main.ts
httpService.axiosRef.interceptors.response.use(
async (response) => {
return response;
},
async (error) => {
const { status , statusText } = error.response;
console.info('main console.info')
throw new HttpException(statusText, status) },
);
мой фильтр httpException (фильтр по умолчанию из документации NestJS)
@Catch(HttpException)
export class HttpExceptionFilter
implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
console.info('filter console.info')
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,
});
}
}
Без карты в функции мой код работает так, как я и предполагал, и моя консоль возвращает только console.info, который отправляет мой перехватчик и фильтр.
Я ожидаю выдать httpException, и мой фильтр обработает ошибку, чтобы код не аварийно завершился.
Не беспокойтесь, спасибо, что исправили
Прежде всего, вам нужен Promise.all, чтобы дождаться завершения всех запросов. Также вы можете добавить уловку для индивидуальной обработки каждой ошибки запроса, если это необходимо. Вот как это может выглядеть:
async fetchData() {
try {
const numbers = [1, 2, 3, 4, 5, 6];
const requests = numbers.map(number =>
this.httpService.axiosRef.get('http://10.55.110.10:7076/axios/test')
.catch(error => {
console.info(`Error for number ${number}:`, error.message);
throw new HttpException(`Failed request for ${number}`, error.response?.status || 500);
})
);
return await Promise.all(requests);
} catch (err) {
console.info('Outer catch block:', err);
throw new HttpException('Something went wrong', 500);
}
}
Для вашего перехватчика Axios в main.ts вы можете упростить его и использовать Promise.reject или также выдать ошибку:
httpService.axiosRef.interceptors.response.use(
response => response,
error => {
console.info('main console.info', error)
// Option 1: return Promise.reject(error);
// Option 2: throw error;
// Option 3: Use your current implementation also should be fine "throw new HttpException(statusText, status);"
}
);
Использование Promise.reject(error) обычно лучше, поскольку оно сохраняет ошибку в цепочке обещаний, позволяя вам обработать ее там, где вы сделали запрос. Это дает вам больше контроля и контекста для обработки ошибок.
Выдача ошибки напрямую (выдача ошибки) может сработать, но это может привести к необработанным отклонениям обещаний, если вы не будете осторожны. Это также может усложнить отладку, поскольку ошибка не будет обнаружена в ожидаемом месте.
Извините, первый вопрос здесь.