UNPKG

@instamenta/grpc-errors

Version:

grpc status codes builder for javascript and typescript grpc server responses

251 lines (250 loc) 8.25 kB
import { Metadata } from '@grpc/grpc-js'; //! GRPC DEFAULT ERRORS const invalidArgumentError = { name: 'InvalidArgument', code: 3, details: '', metadata: new Metadata(), message: 'Invalid argument provided.', }; const deadlineExceededError = { name: 'DeadlineExceeded', code: 4, details: '', metadata: new Metadata(), message: 'Deadline for the operation exceeded.', }; const notFoundError = { name: 'NotFound', code: 5, details: '', metadata: new Metadata(), message: 'Resource not found.', }; const alreadyExistsError = { name: 'AlreadyExists', code: 6, details: '', metadata: new Metadata(), message: 'Resource already exists.', }; const permissionDeniedError = { name: 'PermissionDenied', code: 7, details: '', metadata: new Metadata(), message: 'Permission denied for the operation.', }; const internalError = { name: 'Internal', code: 13, details: 'Server ran into unexpected internal error.', metadata: new Metadata(), message: 'Internal server error.', }; const unavailableError = { name: 'Unavailable', code: 14, details: '', metadata: new Metadata(), message: 'Service unavailable.', }; const dataLossError = { name: 'DataLoss', code: 15, details: '', metadata: new Metadata(), message: 'Data loss occurred.', }; const unauthenticatedError = { name: 'Unauthenticated', code: 16, details: '', metadata: new Metadata(), message: 'Request not authenticated.', }; const failedPreconditionError = { name: 'FailedPrecondition', code: 9, details: '', metadata: new Metadata(), message: 'Operation failed precondition check.', }; const validationError = { name: 'GrpcValidationError', code: 3, details: '', metadata: new Metadata(), message: 'gRPC validation error occurred.', }; const unauthorizedError = { name: 'GrpcUnauthorized', code: 16, details: '', metadata: new Metadata(), message: 'gRPC unauthorized access.', }; const resourceNotFoundError = { name: 'GrpcResourceNotFound', code: 5, details: '', metadata: new Metadata(), message: 'gRPC resource not found.', }; /** Tired of boring old meta whose methods cant be chained? Try this! Simple yet wonderful */ export class Meta { #metadata = new Metadata(); set(key, value) { this.#metadata.set(key, value); return this; } get() { return this.#metadata; } static build() { return new Meta(); } } /** * * Class that provides utility functions for managing gRPC errors. Logging meaningful errors to the console. * * ! With unmatched type safety and extendability! * * @template T - string literal type representing gRPC error keys. * @class GrpcErrors */ export default class GrpcErrors { K = { INVALID_ARGUMENT: 'INVALID_ARGUMENT', DEADLINE_EXCEEDED: 'DEADLINE_EXCEEDED', NOT_FOUND: 'NOT_FOUND', ALREADY_EXISTS: 'ALREADY_EXISTS', PERMISSION_DENIED: 'PERMISSION_DENIED', INTERNAL: 'INTERNAL', UNAVAILABLE: 'UNAVAILABLE', DATA_LOSS: 'DATA_LOSS', UNAUTHENTICATED: 'UNAUTHENTICATED', FAILED_PRECONDITION: 'FAILED_PRECONDITION', VALIDATION: 'VALIDATION', UNAUTHORIZED: 'UNAUTHORIZED', RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND', }; /** * A record of gRPC errors, where keys correspond to error codes * and values contain error details. */ ERRORS = { INVALID_ARGUMENT: invalidArgumentError, DEADLINE_EXCEEDED: deadlineExceededError, NOT_FOUND: notFoundError, ALREADY_EXISTS: alreadyExistsError, PERMISSION_DENIED: permissionDeniedError, INTERNAL: internalError, UNAVAILABLE: unavailableError, DATA_LOSS: dataLossError, UNAUTHENTICATED: unauthenticatedError, FAILED_PRECONDITION: failedPreconditionError, VALIDATION: validationError, UNAUTHORIZED: unauthorizedError, RESOURCE_NOT_FOUND: resourceNotFoundError, }; /** * * Creates and returns a new instance of the GrpcErrors class. * * @template T - string literal type representing gRPC error keys. * @returns - new instance of the GrpcErrors class. */ static getInstance() { return new GrpcErrors(); } /** * * Extends the ERRORS record with a custom gRPC error object. * * @param _key - The key representing the custom gRPC error type. * @param _error - The custom gRPC error object to add to the ERRORS record. * @param _metadata - Additional metadata to attach to the custom gRPC error (if available). * @param _details - Additional details about the custom gRPC error (if available). */ EXTEND({ _key, _error, _metadata = null, _details = null, }) { this.ERRORS[_key] = _error; } /** * * Throws a gRPC error and logs it. * * @param _key - The key representing the gRPC error type. * @param _source - The source of the error (if available). * @param _metadata - Additional metadata to attach to the gRPC error. * @param _details - Additional details about the error (if available). * @returns - The thrown gRPC error response. */ T({ _key, _source = null, _metadata = null, _details = null, }) { const key = String(_key); console.log(_source ? `[ Emitting GRPC ERROR: [ ${key} ] from "${_source}" ]` : `[ Emitting ERROR: [ ${key} ] ]`); const _error = this.ERRORS[_key]; if (_metadata) _error.metadata = _metadata; if (_details) _error.details = _details; return _error; } /** * * Emits a gRPC error on a writable stream and logs it. * * @param call - The writable stream on which to emit the gRPC error. * @param _key - The key representing the gRPC error type. * @param _source - The source of the error (if available). * @param _metadata - Additional metadata to attach to the gRPC error. * @param _details - Additional details about the error (if available). */ E({ call, _key, _source = null, _metadata = null, _details = null, }) { const key = String(_key); const _error = this.ERRORS[_key]; if (_metadata) _error.metadata = _metadata; if (_details) _error.details = _details; call.emit('error', _error); return console.log(_source ? `[ Emitting GRPC ERROR: [ ${key} ] from "${_source}" ]` : `[ Emitting ERROR: [ ${key} ] ]`); } /** * * Calls a callback function with a gRPC error and logs it. * * @param callback - The callback function to call with the gRPC error. * @param _key - The key representing the gRPC error type. * @param _source - The source of the error (if available). * @param _metadata - Additional metadata to attach to the gRPC error. (if available). * @param _details - Additional details about the error (if available). */ CB({ callback, _key, _source = null, _metadata = null, _details = null, }) { const key = String(_key); const _error = this.ERRORS[_key]; if (_metadata) _error.metadata = _metadata; if (_details) _error.details = _details; callback(_error); return console.log(_source ? `[ Emitting GRPC ERROR: [ ${key} ] from "${_source}" ]` : `[ Emitting ERROR: [ ${key} ] ]`); } /** * * Converts a Zod error to a gRPC error response with metadata and details. * * @param error - The Zod error to convert. * @returns - The gRPC error response. */ handleZodError(error) { const _error = this.ERRORS.VALIDATION; const _metadata = new Metadata(); error?.errors?.forEach((e, i) => { _metadata.set(`error_${i}`, e.message); }); _error.metadata = _metadata; _error.details = error?.errors?.map((e) => e.message).join(', '); return _error; } } /** * * Get default Class instance. * * @type {GrpcErrors<IGrpcErrorKeys>} */ export const w = GrpcErrors.getInstance();