Skip to content

Instantly share code, notes, and snippets.

@omirobarcelo
Created May 12, 2020 12:12
Show Gist options
  • Save omirobarcelo/6fa0c7fe963bf225bb814341c0c9ff94 to your computer and use it in GitHub Desktop.
Save omirobarcelo/6fa0c7fe963bf225bb814341c0c9ff94 to your computer and use it in GitHub Desktop.
Excerpt of the Catch decorator for classes and methods
// Decorator factory function
export const Catch = (errorType: any, handler: HandlerFunction): any => {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
// Method decorator
if (descriptor) {
return _generateDescriptor(descriptor, errorType, handler);
}
// Class decorator
else {
// Iterate over class properties except constructor
for (const propertyName of Reflect.ownKeys(target.prototype).filter(prop => prop !== 'constructor')) {
const desc = Object.getOwnPropertyDescriptor(target.prototype, propertyName)!;
const isMethod = desc.value instanceof Function;
if (!isMethod) continue;
Object.defineProperty(target.prototype, propertyName, _generateDescriptor(desc, errorType, handler));
}
}
};
};
function _generateDescriptor(
descriptor: PropertyDescriptor,
errorType: any,
handler: HandlerFunction
): PropertyDescriptor {
// Save a reference to the original method
const originalMethod = descriptor.value;
// Rewrite original method with try/catch wrapper
descriptor.value = function (...args: any[]) {
try {
const result = originalMethod.apply(this, args);
// Check if method is asynchronous
if (result && result instanceof Promise) {
// Return promise
return result.catch((error: any) => {
_handleError(this, errorType, handler, error);
});
}
// Return actual result
return result;
} catch (error) {
_handleError(this, errorType, handler, error);
}
};
return descriptor;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment