Why won't this Azure time triggered function fail? - node.js

I'd like to know why my function is succeeding, even though I'm purposely throwing an exception inside the function. I created a new timer function and all I did is added a try/catch block and an always throwing error:
module.exports = async function (context, myTimer) {
try {
if (myTimer.isPastDue) {
context.log('Node is running late!');
}
context.log('TEST');
throw 'Error occurred';
} catch (err) {
context.log(err);
}
};
After deploying the above function to Azure and manually triggering it, will result in a succeeded function execution and the logs showing 'TEST' but not 'Node is running late!':
2022-04-08T13:32:30Z [Information] TEST
2022-04-08T13:32:30Z [Information] Executed 'Functions.TEST' (Succeeded, Id=..., Duration=36ms)
the docs only state that I should use a try/catch at the highest level of the function. I couldn't find any information on why this function would succeed with an error happening in execution.
Any help will be appreciated, many thanks in advance!

It does not fail because you are catching the error, meaning it is not surfaced, it expects you to actively decide what to do, log and re throw the exception is one option, log only is another it really depends on your business needs.
You need to either remove the try/catch blocks or add a throw to your catch similar to this
catch (err) {
context.log(err);
throw;
}

Related

Error: Transaction rejected with non-error: undefined

I am using knex npm version 0.15.2. while Rollback the transaction I'm getting the following error:
Error: Transaction rejected with non-error: undefined
Trx.rollback()
above function used for rollback.
Same code working for knex version 0.12.6
This is the function I used for commit/Rollback.
function Commit(pTrx, pIsCommit, pCallback) {
try {
var co = require("co");
var q = require('q');
var Q = q.defer();
co(function* () {
if (pIsCommit) {
yield pTrx.commit();
} else {
yield pTrx.rollback();
}
Q.resolve(pCallback('SUCCESS'));
}).catch(function (error) {
Q.reject(pCallback(error));
});
return Q.promise;
} catch (error) {
console.log(error)
}
}
This code could use some work. :) Here are a few things that pop out:
You don't need co or q anymore. Promises and async/await are built-in and much simpler to use. Async functions automatically return promises that will be resolved with the value returned or rejected if an error is thrown. Learn about async/await here: https://jsao.io/2017/07/how-to-get-use-and-close-a-db-connection-using-async-functions/
You shouldn't return success as a string. If the function completes without throwing an exception, then success is implied. I see people do this from time to time, but it's often for the wrong reasons.
You shouldn't accept callback in a function that returns a promise, it should be one or the other. The caller of your function will either pass a callback or await it's completion.
If you are going to use callbacks, then you should return null as the first parameter when successful. See the last sentence here: https://nodejs.org/en/knowledge/getting-started/control-flow/what-are-callbacks/
Your function name, Commit, starts with an uppercase. This convention is typically used to indicate that the function is a contstructor function and meant to be invoked with the new keyword.
Here's how the function could look once cleaned up:
async function commit(pTrx, pIsCommit) {
// Not using a try/catch. If an error is thrown the promise returned will be rejected.
if (pIsCommit) {
await pTrx.commit();
} else {
await pTrx.rollback();
}
// Not going to return anything. If we get to this point then success is implied when the promise is resolved.
}
A consumer of your function would call it with something like:
async function myWork() {
// do work; get pTrx
try {
await commit(pTrx, true);
// If I get here, then I can assume commit was successful, no need to check a return value of 'SUCCESS'
} catch (err) {
// handle error
}
}
It's hard to say where the issue is with the code in its current state. However, if the issue truly is with Knex, then you should probably post this as an issue in the Knex repo: https://github.com/tgriesser/knex/issues But you should write a reproducible test case that proves its an issue with Knex.

How do I check for failure in AWS Lambda that throws an Exception in Node

I doing a basic set of TDD on AWS Lambda, and noticing that if I create a simple test function:
exports.handler = async (event) => {
// Will always fail
throw "Failed to execute - this is a failure function that will always fail";
};
That when I invoke it through the SDK with com.amazonaws.services.lambda.model.InvokeRequest the response code for this function always comes back as 200, and the Error Log is empty!
I'm wondering if I'm doing something wrong in terms of invoking and asking for errors here; because it seems crazy that a JavaScript function that throws an Exception, and, when I test it reports as execution failed in the AWS Lambda console would return a 200?
I noticed that I'm using the async variant here; so I tried also with a sync variant and a context.fail() call:
exports.handler = (event, context, callback) => {
// Will always fail
try {
throw "Failed to execute - this is a failure function that will always fail";
}
catch(e) {
context.fail(e);
}
};
I would definitely expect this to return a 500 or something, but again, I get a 200!
Lambda has two invocation types.
RequestResponse (synchronous)
event (asynchronous)
As you can see, the problem might not necessarily exist within your lambda function. My suggestion would be to check your code that invokes this lambda to see what kind of invocation type you are using.

Firebase Function returning connection error

I am using firebase functions Database Triggers.
My Function :
exports.function_name = functions.database
.ref("/transact/{entry_type}/{id1}/{id2}/trigger_cross_entry_function")
.onCreate((data, context) => {
console.log("trigger_cross_entry_function value", data.val());
if (data.val() == true) {
console.log("Function Calling parent data");
return data.ref.parent.once('value').then(function(snapshot){
}, function(error) {
// The Promise was rejected.
console.error("THIS IS THE ERROR:"+error);
});
} else {
console.log("Function Returned");
return 0;
}
});
Whenever I want to trigger this function I put trigger_cross_entry_function into that partcular path from the Mobile App. Everything works fine and function is called as expected.
After sometime If I again try to do the same thing it gives me
Function execution took 16 ms, finished with status: 'connection error'
If I restart the function than it again works perfectly.
and If I trigger it continously than it has no issue.
But once I keep it idle and try to trigger it
again after sometime, it gives me this error.
And I am using Firebase Pay as you go Plan.
Also, as you can see I am returning all the promises correctly and function is being triggered everytime but It doesnt go into the function. it just exit with connection error.
What might be the cause for this ? I have a spent a day finding this.
Experiencing the same issue. Looks like Google changed the status of the service to down
https://status.firebase.google.com/incident/Functions/18046
https://status.firebase.google.com/
So most likely the Google side problem.

Catch error inside express route

I have a node.js service that is being called from a main application. I've had issues where an error occurs in the service and the service hangs preventing any other requests from being handled. I have code to catch errors in common places like after doing a mongodb query.
model.aggregate(
[
...
],function (err, result) {
if (err) {
next(err);
}
else {
//other code
}
I am also catching uncaught exceptions and killing the service in this case with the following code.
process.on('uncaughtException', function (er) {
console.error(er.stack);
logger.log('info','Cbt Dev Service crashed',er);
process.exit(1);
});
These seem to be working fine except I occasionally run into issues where an error occurs but isn't caught by either. An exmple of an error in this case is after getting a result from a mongodb query and getting an error like "Cannot read property 'subjectAreas' of undefined. This error seems to get caught by the mongodb middleware. The code looks like this.
function (err, result) {
if (err) {
res.send(errorHandler(err, req));
}
else {
var subjectAreas = result[0].subjectAreas.sort();
}
In this case result is an empty array so obviously throws an error. I understand that I can prevent this with better written code like using try/catch but if I'm not aware this issue exists and the service hangs up again, I don't know what the error is in order to fix it so that's why I need to log it.
Is there something else I can do that will catch these kinds of errors?

Does grunt silent errors in (bluebird) promises?

I have a npm module which has main() function as its starting point.
Now, lets say I throw an Error immediently in that main() as shown below:
function main() {
throw new Error("An error!");
}
And then execute it with node my-app-that-launchers-main.js then obviously, the error is thrown and I get a stacktrace.
If I write a grunt task for this:
var mynpm = require("mynpm");
module.exports = function(grunt) {
grunt.registerTask("build",function() {
mynpm.build();
});
}
And execute it via Grunt, then it fails. The error is thrown and grunt fails, as expected.
However, if I wrap this throw inside a Bluebird Promise:
function main() {
Promise.try(function(resolve) {
throw new Error("An error!");
} ).catch(function() {
console.log("error");
} ).finally(function() {
console.log("finally");
});
}
And run it via node then I see that the catch function is invoked. As expected.
However, if I run the same code via Grunt's registertask, everything becomes dead silent. Nor the catch or the finally is called.
What could be causing this. It seems like Grunt hijacks errors are thrown.
Its a super easy to reproduce this, yet I am so puzzled about why.
Does Grunt hijack errors that are thrown, somehow, so not even the Promise's catch and finally functions gets invoked?
How can the execution and the error handling be so different if its executed manually, compared with if Grunt executes the code?
You are looking to define an async task. This can be done using this.async():
grunt.registerTask("build",function() {
// Tell Grunt this task is asynchronous.
var done = this.async();
mynpm.build();
});
More information about async tasks here : https://gruntjs.com/api/inside-tasks

Resources