-
-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for custom error
catcher for api
#1812
Comments
Concerning errors: I think we can use single Error class with following features: export interface ErrorOptions {
code?: number | string;
cause?: Error;
}
export class Error extends global.Error {
constructor(message: string, options?: number | string | ErrorOptions);
message: string;
stack: string;
code?: number | string;
cause?: Error;
} |
Another option: class DomainError extends Error {
...
}
class MessengerError extends DomainError {
...
static invalidPermission() {
return new MessengerError('Permission denied');
}
static notFound() {
return new MessengerError('Not found');
}
// and so on...
} This neither requires defining a class per each error (1 proposal) nor requires additional functionality to check if a general purpose error received an allowed message (2 proposal). |
I suggest to have ({
parameters: {
a: 'number',
b: 'number',
},
method: async ({ a, b }) => {
const result = a + b;
return result;
},
onError: (error) =>
'code' in error ? error : { message: error.message, code: 500 },
returns: 'number',
}); The goal is to have any custom error handlers in case if API method failed. Inspired from Fastify hooks |
It is just a draft proposal/example of how we can declare a list of the errors with TypeScript. export enum ErrorCode {
notFound = 'NOT_FOUND',
invalidResponse = 'INVALID_RESPONSE',
authenticationError = 'AUTHENTICATION_ERROR',
networkError = 'NETWORK_ERROR',
}
export type ErrorOptions = {
message: string;
data?: any;
};
const record: Record<ErrorCode, ErrorOptions> = {
NOT_FOUND: { message: 'Not found' },
INVALID_RESPONSE: {
message: 'Invalid response. Please try again later.',
data: { additionalFields: 'something' },
},
AUTHENTICATION_ERROR: {
message: 'Authentication failed',
},
NETWORK_ERROR: {
message: 'Network error occurred',
},
};
export const createError = (code: ErrorCode) => ({ code, ...record[code] });
console.log(createError(ErrorCode.notFound));
|
// error names
const DOMAIN_ERROR_NAME = {
NotFound = 'NotFound',
Forbidden = 'Forbidden',
SomeEntityIsDeactivated = 'SomeEntityIsDeactivated',
...
};
// domain layer
throw new DomainError(DOMAIN_ERROR_NAME.NotFound) |
export interface LogFormatError {
toJSON(): Record<string, unknown>;
// compatible with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior.
}
export interface UserFormatError {
toUserError(): Record<string, unknown>;
// allows to provide custom data when error is sent to user
} both interfaces are optional for all Errors. Logger/API will check for those upon handling. |
Endpoint code: ({
parameters: {
person: { domain: 'Person' },
address: { domain: 'Address' },
},
method: async ({ person, address }) => {
const addressId = await api.gs.create(address);
person.address = addressId;
const personId = await api.gs.create(person);
return personId;
},
returns: { type: 'number' },
errors: {
ECONTRACT: 'Invalid arguments',
ECANTSAVE: 'Person and address can not be saved to database',
ERESULT: 'Invalid result',
},
}); We can generate type Code = 'ECONTRACT' | 'ECANTSAVE' | 'ERESULT';
class CustomError {
constructor(message: string, options: { code: Code });
} |
I believe, we need complex examples, not just a code snippet, we need branch/fork with a few files to show how it will work and ready to try branch, for example my proposal: metarhia/Example#233 |
Added my extended proposal - metarhia/Example#234.
Also, I'm not sure if those handlers should be triggered if |
Implemented in Version 3.0.0 |
Describe the problem
It is often not enough to catch any error that arises in the application code and to send error 500 to the client.
Describe the solution
Better solution would be to allow custom API handler wrappers to be provided
Alternatives
No response
Additional context
See https://github.com/metatech-university/NodeJS-Application/pull/4/files#diff-76374afb32b513f9f1f3ad04638ffcfba3c4cd36aa447236a128c2b6ed6c0936R14
The text was updated successfully, but these errors were encountered: