@instamenta/grpc-errors
Version:
grpc status codes builder for javascript and typescript grpc server responses
168 lines (136 loc) • 5.75 kB
Markdown
## 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:
```bash
npm install @instamenta/grpc-errors
```
## Glossary & Function Signatures
```js
/**
* * 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))
```js
/**
* * 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))
```js
/**
* * 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
```js
/**
* * 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
```ts
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
```ts
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.
```ts
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 :)