Javascript ES5/ES6 classes and error handling - javascript

Say I have a class like this
class SomeUIComponentDataStore {
async function getUser() {
try { //do something that can fail}
catch(e) {
// gracefully fail, setting portion of ui to fail state
Sentry.captureException(e); // report to some metrics service
}
}
}
I repeat that pattern for every async function. Where on failure I respond to the error, and then report it to some service (in this case that service is Sentry).
Is there anyway I can create a BaseClass, that will automatically decorate my catch statement with Sentry.caputreException(). Or do i have to manually write it each time a I see an error.

You could define a decorator to reuse that logic and decorate methods that can throw:
function catchError(target, name, descriptor) {
const original = descriptor.value;
if (typeof original === 'function') {
descriptor.value = function(...args) {
try {
return original.apply(this, args);
} catch (e) {
Sentry.captureException(e); // report to some metrics service
}
}
}
}
function catchErrorAsync(target, name, descriptor) {
const original = descriptor.value;
if (typeof original === 'function') {
descriptor.value = async function(...args) {
try {
return await original.apply(this, args);
} catch (e) {
Sentry.captureException(e); // report to some metrics service
}
}
}
}
class SomeUIComponentDataStore {
#catchErrorAsync
async getUser() {
//do something that can fail
}
#catchError
otherMethod() {
//do something that can fail
}
}

You could create a base class with the Sentry.captureException(e);, and then have overrideable functions for the custom try/catch functionality.
class BaseClass {
function onGetUser() {
throw new Error("Method not implemented");
}
function onGetUserFail() {
throw new Error("Method not implemented");
}
async function getUser() {
try {
onGetUser();
} catch (e) {
onGetUserFail();
Sentry.captureException(e);
}
}
}
class SomeUIComponentDataStore extends BaseClass {
function onGetUser() {
// do something
}
function onGetUserFail() {
// do something
}
}

Related

Early return from a subscribe block in a function

I am new to JavaScript. I am trying to do an early return on error from a subscribe block.
This is what I have
public doSomething() {
this.updateData(data)
.subscribe((result) => {
// do something
},
(err) => {
console.error("Error");
return;
// require an early return from the block
// so rest of the function isn't executed.
});
// do other work
}
Any pointers will be appreciated.
The best solution would be:
public doSomething() {
this.updateData(data)
.subscribe((result) => {
// do something
// do other work
},
(err) => {
console.error("Error");
return;
// require an early return from the block
// so rest of the function isn't executed.
});
}
But you can also use await with async:
public async doSomething() {
const result = await this.updateData(data);
if (!result) return;
// do other things
}

Angular method decorator error handling with subscriptions

Currently, I have an angular application with a method decorator to handle errors of all the methods in the component. It catches all the errors from methods, But it is unable to catch the error inside subscribe. Any suggestions to do this?
This is my current code.
This is the sampling method I want to catch the errors
#logActionErrors()
getEmailSettings() {
this.sharedService.getSMTPConfigurations().subscribe(() => {
throw('this is an error');
}, (ex) =>{
console.log(ex);
})
}
This is my Method Decorator
export function logActionErrors(): any {
return function (target: Function, methodName: string, descriptor: any) {
const method = descriptor.value;
descriptor.value = function (...args: any[]) {
try {
let result = method.apply(this, args);
// Check if method is asynchronous
if (result && result instanceof Promise) {
// Return promise
return result.catch((error: any) => {
handleError(error, methodName, args, target.constructor.name);
});
}
if(result && result instanceof Observable ){
console.log(methodName);
result.pipe(catchError((error: any) => {
console.log(error);
handleError(error, methodName, args, this.constructor.name);
return result
}))
}
// Return actual result
return result;
} catch (error:any) {
handleError(error, methodName, args, target.constructor.name);
}
}
return descriptor;
}
}
I want to catch this throw('this is an error'); error on this sample. any suggestions to do this?

JS Using onSuccess() syntax

I have some code and I just see to be doing something wrong with the syntax.
Here is the code:
async mymethod(onSuccess, onFailure) {
try {
// Do some here
onSuccess()
}
catch (e) {
//this was an error
}
}
What I want to do is its onSuccess() I want to do something.
Tried:
onSuccess((function() {
// Do something
}))
But there seems to be a syntax error.
How do I use onSuccess() and do something with it?
You're missing the function keyword:
async function mymethod(onSuccess, onFailure) {
try {
// Do some here
onSuccess()
}
catch (e) {
//this was an error
onFailure()
}
}
mymethod(() => alert('success'), () => alert('failure'));
Since you are using a typescript and a class you need to include the public access modifier as methods are private by default.
class Foo {
public async mymethod(onSuccess, onFailure) {
try {
// Do some here
onSuccess()
}
catch (e) {
//this was an error
onFailure()
}
}
}
const foo = new Foo();
foo.mymethod(() => { console.log('success') }, () => { console.log('failure') });

decorators: "this" is undefined when accessed in descriptor.value

I am trying out decorators, I have written a decorator that basically returns a new function that does some `console.log.
This is what my decorator looks like:
function test(target, name, descriptor) {
const original = descriptor.value;
console.log("bbau");
if (typeof original === 'function') {
descriptor.value = function (...args) {
console.log(`Arguments: ${args}`);
try {
console.log("executing");
const result = original.apply(this, args);
console.log("done");
console.log(`Result: ${result}`);
return result;
} catch (e) {
console.log(`Error: ${e}`);
throw e;
}
}
}
return descriptor;
}
And this is how I am using it:
class TestController extends BaseController<//..> {
// ...
#test
testIt(req: Request, res: Response) : Response {
this.sendResponse();
}
sendResponse(options: ISendResponseOptions, res: Response) : Response {
// return response
}
}
``
However, when executed an error is raised: Error: TypeError: Cannot read property 'sendResponse' of undefined.
Any thoughts about what it could be? Thanks!
You should generally use an arrow function when you want to capture this from the context you declared the function in (or when this does not matter). In this case you really want this to be the object the function was called on so you should use a regular function :
const test = (target, name, descriptor) => {
const original = descriptor.value;
if (typeof original === 'function') {
descriptor.value = function (...args) {
console.log(`Arguments: ${args}`);
try {
console.log("executing");
const result = original.apply(this, args);
console.log("done");
console.log(`Result: ${result}`);
return result;
} catch (e) {
console.log(`Error: ${e}`);
throw e;
}
}
}
return descriptor;
}
You can test it out in the playground
If you use this function as a parameter to another function you should also call bind to set this for the function (otherwise the caller will determine the value of this):
router.route("/").post(testController.testIt.bind(testController))

method babel decorators isn't executed

I'm using the babel 7 decorator plugin and I have a simple class and I want to decorate each method in a simple try catch wrapper.
This is what've done:
const errorHandler = () => {
return (target, property, descriptor) => {
try {
return descriptor
} catch (e) {
console.error('error from the decorator', e)
}
}
}
In this is a sample of my class:
class Example {
#errorHandler
addComponent() {
throw new Error('Error')
}
}
But when I'm executing the function it's not going throw the decorator before execution, only pre-evaluating when the class is being initialized.
any ideas?
You are returning descriptor, which is a function object and it gets executed by caller outside your try/catch block. To intercept exception - you should execute descriptor yourself.
The correct code is:
const errorHandler = (target, property, descriptor) => {
const original = descriptor.value;
if (typeof original === 'function') {
descriptor.value = async function(...args) {
try {
return await original.apply(this, args);
} catch (e) {
console.error('error from the decorator', e)
}
}
}
}
class Example {
#errorHandler
addComponent() {
throw new Error('Error')
}
}
new Example().addComponent();

Categories

Resources