I have dozens of functions with try catch block to handle and log any error occurred.
function add(a, b) {
try {
return a + b;
} catch (error) {
log.error(error.message + ' in add');
}
}
As this try catch statements have same kind of code for each function mentioning error message and the function name in each log, I want some way to avoid writing try catch for each function and want it to be added automatically. My function should be like below one but should work like above one.
function add(a, b) {
return a + b;
}
How could it be possible?
You can wrap your functions up using closures.
For logging, you can try using Function.name, but for meaningful information this rules out arrow functions and otherwise anonymous functions. This could be solved by explicitly passing a name string to the wrap function, but...
There is of course no guarantee the returned function is used via an identifier related to the original name (whatever vs anError below).
const wrap = func => (...args) => {
try {
return func.apply(this, args);
} catch (e) {
console.error(`${e} in ${func.name}`);
}
};
const add = wrap((a, b) => a + b);
const fail = wrap(t => {
if (t)
throw new Error('foo');
});
const whatever = wrap(function anError () {
throw 'an error';
});
console.log(add(1, 2));
fail(false);
fail(true);
whatever();
Combined output:
3
Error: foo in
an error in anError
can you try with callback...
function add(a, b){
return a + b;
}
function substract(a, b){
return a - b;
}
function calc(a){
try{
const f = Array.prototype.shift.apply(arguments);
return f(...arguments);
}catch(e){
console.log(e.stack);
}
}
calc(substract, 1, 2);
Related
I've seen a few answers but its still a little unclear to me how to go about this.
I have a retry function, whose parameter of fn I'd like to call with the original parameters supplied to it:
function retry(fn, retries=3, err=null) {
if (!retries) {
return Promise.reject(err);
}
return fn().catch(err => {
return retry(fn, (retries - 1), err);
});
}
Is there a clean way to do this in JS?
In short, I'd like to do something like:
function a(b,c,d) { return Promise.resolve(b + c + d) }
retry(a, ...originalParams)
Besides what you've covered yourself, another way would be to wrap your function and it's arguments into a thunk. However, it's not exactly what you would like it to be.
function retry(fn, retries=3, err=null) {
if (!retries) {
return Promise.reject(err);
}
return fn().catch(err => {
return retry(fn, (retries - 1), err);
});
}
function toThunk(fn, ...args) {
// note that we return a new function which closes over
// the function and arguments here (e. g. creating closures)
return () => fn(...args);
}
function sumP(a, b, c) {
return Promise.resolve(a + b + c);
}
// ---
retry(toThunk(sumP, 1, 2, 3)).then(result => {
console.log(result);
});
I want pass quiz from codewars - https://www.codewars.com/kata/53cf7e37e9876c35a60002c9/train/javascript, but I can not avoid an error to pass :"TypeError: add(...) is not a function"
function curryPartial(){
let args= [...arguments]
let fn = args[0]
console.log(fn.length)
function cur(){
let argsCur= [...arguments]
return curryPartial(...args,...argsCur)
}
cur.valueOf = ()=>{
//return args.reduce((a,b)=>a+b)
// console.log(...args)
// const res = +fn(...args.slice(1))
// return res
}
return cur
}
function add(a, b, c) {
return a + b + c;
}
console.log(+curryPartial(add(1,2)(3)))
How I can avoid this error to pass the quiz ?
That's about the add(1,2)(3)
Of cause you get errors, the add function returns a value, by doing add(1,2)(3) you are executing the return value of add(1,2) with passing a 3, which is not a function, so the error has been raised.
the execute statement should be
console.log(+curryPartial(add)(1,2)(3))
// not
console.log(+curryPartial(add(1,2)(3)))
pay attention to the parentheses pair
I'm trying to implement currying function:
function sum(a, b, c) {
console.log('SUM'+JSON.stringify(arguments))
return a + b + c;
}
var curry= function (func,...n) {
return function(...args2) {
//console.log('arg2s'+args2)
return func.apply(this,n.concat(args2));
};
}
curry(sum,1,2)(3) //SUM{"0":1,"1":2,"2":3}, O/P:6
Above gives correct output, but i am not getting the necessity to use apply.
So, if i change my function to below:
var curry= function (func,...n) {
return function(...args2) {
//console.log('arg2s'+args2)
return func(n.concat(args2));
};
}
curry(sum,1,2)(3) //SUM{"0":[1,2,3]} O/P:"1,2,3undefinedundefined"
I basically have two questions here:
Why is the implementation of curry not working when calling func directly?Why is the output such weird ?
2.How do i change my function in a way that i can call it as below and should return sum:
curry(1)(2)(3)/curry(1,2)(3)/curry(1,2,3) etc instead of the way i'm calling currently.
I could find some solutions on the web, but couldn't understand .
ex:
function curry(func) {
return function curriedFunc(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args1) {
return curriedFunc.apply(this, args.concat(args1));
}
}
};
}
Any help would be highly appreciated !!
Your func accepts three arguments: a, b, and c. When you do:
return func(n.concat(args2));
you're passing it one argument, an array. It's equivalent to:
const arr = n.concat(args2);
return func(arr);
Sounds like you'd want to spread the arguments into the call of func instead:
return func(...n, ...args2)
With spread syntax, each item from the iterable is put into a parameter. Eg, if the n array has one item, it gets set as the first argument passed to func, and if args2 has 2 items, the first gets set as the second argument passed, and the second gets set as the third argument passed.
function sum(a, b, c) {
console.log('SUM' + JSON.stringify(arguments))
return a + b + c;
}
var curry = function(func, ...n) {
return function(...args2) {
return func(...n, ...args2);
};
}
curry(sum, 1, 2)(3);
How do i change my function in a way that i can call it as below and should return sum: curry(1)(2)(3)/curry(1,2)(3)/curry(1,2,3) etc
Keep track of the total number of arguments passed in a closure created the first time the function is called. In the returned function, push all arguments to the array, and if the array's length is 3, return the sum, otherwise return the function again:
function sum(a, b, c) {
return a + b + c;
}
var curry = function(func, ...argsSoFar) {
const neededArgs = func.length;
const returnedFn = (...args) => {
argsSoFar.push(...args);
if (argsSoFar.length === neededArgs) {
return func(...argsSoFar);
} else {
return returnedFn;
}
};
return returnedFn;
}
console.log(
curry(sum, 1, 2)(3),
curry(sum)(1, 2)(3),
curry(sum)(1)(2, 3),
curry(sum)(1)(2)(3),
);
My test function reverseAdd call another function add that is defined in same module.
I need to test, if test function call another.
Module
function add(a, b) {
return a + b;
}
function reverseAdd(a, b) {
add(b, a);
}
module.exports = {
add,
reverseAdd
}
Test
const exp = require('./add');
describe('add', () => {
it('should add two numbers', () => {
expect(exp.add(1, 2)).toBe(3);
});
it('should add two numbers', () => {
exp.add = jest.fn();
exp.reverseAdd();
expect(exp.add).toHaveBeenCalledTimes(1);
});
});
Result
Expected mock function to have been called one time, but it was called zero
As I understand wraped function is another function, and it is not called in test function.
How can I wrap/spy the function add?
playground: https://repl.it/repls/WoodenElectricInstances
Thanks #ltamajs, I found solution.
Need to rewrite module to
function add(a, b) {
return a + b;
}
function reverseAdd(a, b) {
module.exports.add(b, a); <----- here changes
}
module.exports = {
add,
reverseAdd
}
Well, is it possible to use function as return statement in outer function?
I want to use something like this:
function returnFunction(){
// some magic (unknown for me) code here
}
// and here is just usual function
function calculateFunction(a,b){
var result = a + b;
returnFunction();
showResult(result);
}
So, the function above should only calculate "a + b" but don't show it result because "returnFunction" should play a role of native "return" statement in "calculateFunction".
I know that I can always do something like this:
function calculateFunction(a,b){
var result = a + b;
if( needReturnFunction() ) return;
showResult(result); // won't run if above true
}
But my point is to actually simulate "return", replace it.
So, if it possible, what the "magic code" then?
The only way I can imagine something like that is if you throw
function returnFunction(){
if (shouldReturn) throw 'return';
}
// and here is just usual function
function calculateFunction(a,b){
var result = a + b;
returnFunction();
showResult(result); // won't run if above throws
}
But then you would have to always use try, catch:
try {
calculateFunction(a, b);
}
catch (err) {
// if error thrown is 'return' then ignore
if (err !== 'return') throw err;
}
This is definitely not something nice to do. You should probably re-think your code.