У меня есть гнездо JS Контроллер: search.controller.ts
import { Body, Controller, Post, Req, UseFilters } from '@nestjs/common';
import { HttpExceptionFilter } from '../exception/http-exception.filter';
import { SearchData } from './models/search-data.model';
import { SearchResults } from 'interfaces';
import { SearchService } from './search.service';
@Controller('')
@UseFilters(HttpExceptionFilter)
export class SearchController {
constructor(private searchService: SearchService) {}
@Post('api/search')
async searchDataById(
@Body() searchData: SearchData,
@Req() req
): Promise<SearchResults> {
return await this.searchService.getSearchResultsById(
searchData,
token
);
}
}
Этот контроллер поиска использует Фильтры с именем HttpExceptionFilter . Этот фильтр срабатывает всякий раз, когда выбрасывается HttpException . Я создал ServiceException , который расширяет HttpException . Я выдаю новый ServiceException () всякий раз, когда возникает ошибка.
HttpExceptionFilter
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException
} from '@nestjs/common';
import { ErrorDetails } from './error-details.interface';
import { HTTP_ERRORS } from './errors.constant';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const status = exception.getStatus();
const api = exception.getResponse() as string;
const errorDetails = this.getErrorDetails(api, status);
response.status(status).json({
status: status,
title: errorDetails.title,
message: errorDetails.message
});
}
private getErrorDetails(api: string, status: string | number): ErrorDetails {
const errorDetails: ErrorDetails = {
title: HTTP_ERRORS.GENERAL.ERROR.title,
message: HTTP_ERRORS.GENERAL.ERROR.message
};
// if rejection status is logged out or toke expired then redirect to login
if (
HTTP_ERRORS.hasOwnProperty(api) &&
HTTP_ERRORS[api].hasOwnProperty(status)
) {
errorDetails.title = HTTP_ERRORS[api][status].title;
errorDetails.message = HTTP_ERRORS[api][status].message;
}
return errorDetails;
}
}
ServiceException
import { HttpException } from '@nestjs/common';
export class ServiceException extends HttpException {
constructor(private details, private code) {
super(details, code);
}
}
search.service.ts
import { APIS } from '../app.constants';
import { HttpService, HttpStatus, Injectable } from '@nestjs/common';
import { SearchData, SearchResultSchema } from './models/search-data.model';
import { AppConfigService } from '../app-config/app-config.service';
import { AxiosResponse } from 'axios';
import { DataMappingPayload } from './models/data-mapping-payload.model';
import { SEARCH_SCHEMAS } from './search.constants';
import { SearchModelMapper } from './search-model-mapper.service';
import { SearchResults } from '@delfi-data-management/interfaces';
import { ServiceException } from '../exception/service.exception';
@Injectable()
export class SearchService {
constructor(
private searchModelMapper: SearchModelMapper,
private configService: AppConfigService,
private readonly httpService: HttpService
) {}
// eslint-disable-next-line max-lines-per-function
async getSearchResultsById(
searchData: SearchData,
stoken: string
): Promise<SearchResults> {
if (searchData.filters.collectionId && searchData.viewType) {
if (
Object.values(SEARCH_SCHEMAS).indexOf(
searchData.viewType as SEARCH_SCHEMAS
) !== -1
) {
try {
...... some code cant paste here
return this.searchModelMapper.generateSearchResults(
kinds,
mappingPayload,
searchResultsAPI.data.results
);
} catch (error) {
throw new ServiceException(
APIS.SEARCH,
HttpStatus.INTERNAL_SERVER_ERROR
);
}
} else {
throw new ServiceException(APIS.SEARCH, HttpStatus.BAD_REQUEST);
}
} else if (!searchData.filters.collectionId) {
throw new ServiceException(APIS.SEARCH, HttpStatus.BAD_REQUEST);
} else {
throw new ServiceException(APIS.SEARCH, HttpStatus.BAD_REQUEST);
}
}
Теперь эта вещь никогда не доходит до HttpExceptionFilter в модульных тестах
search.service.spe c .ts
beforeEach(async () => {
const app = await Test.createTestingModule({
imports: [AppConfigModule, HttpModule, SearchModule]
}).compile();
searchService = app.get<SearchService>(SearchService);
});
it('should throw error message if viewType not provided', () => {
const searchDataquery = {
filters: {
collectionId: 'accd'
},
viewType: ''
};
const result = searchService.getSearchResultsById(searchDataquery, 'abc');
result.catch((error) => {
expect(error.response).toEqual(
generateSearchResultsErrorResponse.viewTypeError
);
});
});
Есть ли причина, по которой генерировать новое ServiceException, которое внутренне вызывает HttpException, не вызывает HttpExceptionFilter?