1.3.17 • Published 7 months ago

@instamenta/grpc-errors v1.3.17

Weekly downloads
-
License
MIT
Repository
-
Last release
7 months ago

GrpcError Builder 👷‍♂️

GrpcError Builder is a super simple package that simplifies the process of creating gRPC error objects with customizable error codes, details, and metadata for JavaScript and TypeScript gRPC server responses.

Installation 🛠️

You can install GrpcError using npm:

npm install @instamenta/grpc-errors

Glossary & Function Signatures

/**
 * * 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).
 */
  • GrpcErrorsBuilder.CB - Stands for Callback - used to internally call callback((the 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).
 */
  • GrpcErrorsBuilder.E - Stands for Emit - used to internally call.emit('error', (the 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.
 */
  • GrpcErrorsBuilder.T - Stands for Throw - used to build more complex errors

  • GrpcErrorsBuilder.K - Stands for Key - used to get specific key of errors

/**
 * * 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).
 */
  • GrpcErrorsBuilder.EXTEND - used to add new errors to the class, pass interface while creating the class to get type safety and autocomplete

Class Signature

class GrpcErrors<T extends IGrpcErrorKeys> {} // <T> Provide IGrpcErrorKeys if needed or additional interface if you have custom errors;

Errors coming with package

  • INVALID_ARGUMENT
  • DEADLINE_EXCEEDED
  • NOT_FOUND
  • ALREADY_EXISTS
  • PERMISSION_DENIED
  • INTERNAL
  • UNAVAILABLE
  • DATA_LOSS
  • UNAUTHENTICATED
  • FAILED_PRECONDITION
  • VALIDATION
  • UNAUTHORIZED
  • RESOURCE_NOT_FOUND

Sample of ServerErrorResponse

const unauthenticatedError: ServerErrorResponse = {
    name: 'Unauthenticated',
    code: 16, //? GRPC error code for "UNAUTHENTICATED"
    details: '',
    metadata: new Metadata(),
    message: 'Request not authenticated.',
};

Example

This is simple endpoint of my project where you can see the gRPC error builder imported as 'w'.

  • you can only see my new package "Vlogger" being used here which aims to simplify, make more colorful & simplify logging to the console in JavaScript and Typescript.
import type Vlogger from "@instamenta/vlogger";
import type {IVlog} from "@instamenta/vlogger";
import {w} from "@instamenta/grpc-errors";

export default class ThreadsService implements IThreadsServer {

    readonly #repository: ThreadRepository;
    readonly #vlog: IVlog;

    constructor(threadRepository: ThreadRepository, vlogger: Vlogger) {
        this.#repository = threadRepository;
        this.#vlog = vlogger.getVlogger('ThreadsService');
    }
    
    public async delete(
        call: ServerUnaryCall<PI.IdRequest, PI.ThreadModel>,
        callback: sendUnaryData<PI.ThreadModel>
    ): Promise<void> {
        try {
            this.#vlog.debug({d: call.request.toObject(), f: 'delete'});
            const {id: threadId} = zod.IdRequest.parse(new IdRequestExtractor(call.request).extract());

            this.#repository.deleteById(threadId)
                .then((model: ThreadModel | null) => model instanceof ThreadModel
                    ? callback(null, new ThreadBuilder(model).build_GRPC())
                    : w.CB({callback, _key: w.K.NOT_FOUND}));
        } catch (e: Error | ZodError | MongoError | unknown) {
            (e instanceof ZodError) ? callback(w.handleZodError(e)) : w.CB({callback, _key: w.K.INTERNAL});
            this.#vlog.error({e})
        }
    }

    public async getOne(
        call: ServerUnaryCall<PI.IdRequest, PI.ThreadModel>,
        callback: sendUnaryData<PI.ThreadModel>
    ): Promise<void> {
        try {
            this.#vlog.debug({d: call.request.toObject(), f: 'getOne'});
            const {id: threadId} = zod.IdRequest.parse(new IdRequestExtractor(call.request).extract());

            this.#repository.getOneById(threadId)
                .then((model: ThreadModel | null) => model ? callback(null, new ThreadBuilder(model).build_GRPC())
                    : w.CB({callback, _key: w.K.NOT_FOUND}));
        } catch (e: ZodError | unknown) {
            (e instanceof ZodError) ? callback(w.handleZodError(e)) : w.CB({callback, _key: w.K.INTERNAL});
            this.#vlog.error({e})
        }
    }
}

Usage 🚀

To use just check the source code.

License 📜

This package is not licensed feel free to use it however you like :)

1.3.17

7 months ago

1.3.16

7 months ago

1.3.15

7 months ago

1.3.14

7 months ago

1.3.13

7 months ago

1.3.12

7 months ago

1.3.11

7 months ago

1.3.10

7 months ago

1.3.9

7 months ago

1.3.8

7 months ago

1.3.7

8 months ago

1.3.6

8 months ago

1.3.5

8 months ago

1.3.4

8 months ago