@restorecommerce/chassis-srv
Version:
Restore Commerce microservice chassis
76 lines • 2.77 kB
JavaScript
import { ServerError } from 'nice-grpc';
import { isAbortError } from 'abort-controller-x';
import { metadataPassThrough } from '@restorecommerce/grpc-client/dist/middleware.js';
import { randomUUID } from 'node:crypto';
const tracingHeader = 'x-request-id';
export async function* tracingMiddleware(call, context) {
const nextID = context.metadata.get(tracingHeader) || randomUUID();
context.metadata?.set(tracingHeader, nextID);
return yield* call.next(call.request, {
...context,
rid: nextID
});
}
export const loggingMiddleware = (logger) => {
return async function* (call, context) {
const { path } = call.method;
logger.verbose(`[rid: ${context.rid}] received request to method ${path}`, call.request);
try {
const response = yield* call.next(call.request, context);
logger.verbose(`[rid: ${context.rid}] request to method ${path} response sent`, { request: call.request });
return response;
}
catch (error) {
if (error instanceof ServerError) {
logger.error(`${context.rid} request to method ${path} server error`, {
message: error.details,
code: error.code
});
}
else if (isAbortError(error)) {
logger.error(`${context.rid} request to method ${path} cancel`, {
message: error.message,
stack: error.stack
});
}
else {
logger.error(`${context.rid} request to method ${path} error`, {
message: error.message,
stack: error.stack
});
}
return {
status: {
code: 500,
message: error.message
}
};
}
};
};
function bindAsyncGenerator(store, generator) {
const ctx = store.getStore();
return {
next: () => store.run(ctx, generator.next.bind(generator)),
return: (args) => store.run(ctx, generator.return.bind(generator), args),
throw: (args) => store.run(ctx, generator.throw.bind(generator), args),
[Symbol.asyncIterator]() {
return this;
},
[Symbol.asyncDispose]() {
return null;
}
};
}
export async function* metaMiddleware(call, context) {
const mapped = {};
for (const [a, b] of context.metadata) {
mapped[a] = b;
}
const val = JSON.stringify(mapped);
metadataPassThrough.enterWith(val);
return yield* bindAsyncGenerator(metadataPassThrough, call.next(call.request, {
...context,
}));
}
//# sourceMappingURL=middlewares.js.map