I have an NestJS app which is a service for other applications to handle each of their own app and document related processess. I am using an Interceptor to capture every request and response and updating a database for auditing purposes.
A problem I am running into is implementing a way to update each request's progression...
export enum RequestDetails {
INPROGRESS = 'INPROGRESS',
COMPLETE = 'COMPLETE',
ERROR = 'ERROR'
}
Meaning in the interceptor I have a object where I am handling the initial state of the request and updating the database, see below.
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
// any route with this decorator will not be logged.
const preventReqResLog: boolean = this.reflector.get<boolean>('preventReqResLog', context.getHandler());
const req: Request = context.switchToHttp().getRequest();
const { statusCode } = context.switchToHttp().getResponse();
const { originalUrl, method, params, query, headers, body } = req;
const isHealthRoute: boolean = originalUrl.endsWith('health/detailed') || originalUrl.endsWith('health');
const timeStamp: string = this.dSUtil.getCurrentTS();
const requestDetails: DSRequestRequestDetails = new DSRequestRequestDetails();
requestDetails.appName = body.appName;
requestDetails.customerName = body.customerName;
requestDetails.originalUrl = originalUrl;
requestDetails.method = method;
requestDetails.params = params;
requestDetails.id = headers.awsrequestid as string;
requestDetails.type = EItemType.REQUEST;
requestDetails.query = query;
requestDetails.headers = headers;
requestDetails.requestState = EDSRequestRequestDetails.INPROGRESS; // in progress
requestDetails.timeStamp = timeStamp;
try {
if (!isHealthRoute && !preventReqResLog) {
this.logService.info(
JSON.stringify({
originalUrl,
method,
params,
query,
headers,
requestId: DSRequestContextService.getCurrentReqId(),
body
})
);
(async () => {
await this.dsDynamoDBService
.putItem({
TableName: this.dsConfig.aws.dynamoDB.table,
Item: requestDetails
})
.then((response) => response)
.catch((error) => {
this.logService.error(error);
});
})();
}
(req as any).isLogReqRes = !preventReqResLog;
} catch (error) {
this.logService.error(error);
}
But how would I update each request with its progress considering they're asynchronus?
I imagine if there was an error I should adding this line to the catch
in the database call right?
requestDetails.requestState = EDSRequestRequestDetails.ERROR;
And if its successsfull do I update this in the
`return next.handle().pipe(
tap((data) => {
try {
if (!isHealthRoute && data) {
data.requestId = DSRequestContextService.getCurrentReqId();
}
if (!isHealthRoute && !preventReqResLog) {
this.logService.info(
JSON.stringify({
originalUrl,
method,
params,
query,
headers,
requestId: DSRequestContextService.getCurrentReqId(),
statusCode,
data
})
);
(async () => {
requestDetails.requestState = EDSRequestRequestDetails.COMPLETE;
await this.dsDynamoDBService
.putItem({
TableName: this.dsConfig.aws.dynamoDB.table,
Item: requestDetails
})
.then((response) => response)
.catch((error) => {
this.logService.error(error);
});
})();
}
} catch (error) {
this.logService.error(error);
}
})
);`
I think what is confusing me is let's say Request A
comes through and being that it is async
it takes some time, and then Request B
comes through and also takes time, but then Request C
comes through and is pretty fast. Will the interceptor just wait and update requestDetails.requestState
based on my logic for each?
Is there more to this? Thanks! Any help would be appreciated!