GAS 'Unexpected exception upon serializing continuation' error present when run from menu, but not present when run from editor - google-apps-script

A GAS function is triggered from a sheet custom menu. This function is executed daily and has worked without error for weeks. A couple days ago, users started to see the so unhelpful "Unexpected exception upon serializing continuation" error. I have found that I can execute the exact same function from the code editor without error, but consistently re-produce the error when using the menu. More odd, everything I expect the function (and others called by it) appears to be completing correct.
How can I trouble-shoot an error and file a problem report with google when I can't run isolate parts of the script to narrow down the problem?

Encapsulate your trigger-code inside a try-catch block:
function calledByTriggerOrMenu () {
try {
doTheThings();
}
catch (e) {
Logger.log ("Catched something: "+e+"\n"+e.stack);
}
}
Then you know exactly where the error occured

Related

Uncaught (in promise) -- How to find the source of the problem in a Deno program

I'm having trouble with my Deno program. I'm getting messages like this:
error: Uncaught (in promise) Error: No such host is known. (os error 11001)
at deno:core/01_core.js:106:46
at unwrapOpResult (deno:core/01_core.js:126:13)
at async Object.connect (deno:extensions/net/01_net.js:219:13)
Then deno exits.
I don't know how to debug this. This stack trace only points to code that comes with Deno, not to my code.
I've searched my code and I've put a .catch() or a try/catch everywhere I can think of, but that did not help.
Is there anything I can do to help me find the problem? I'd love it if I could get a complete stack dump. Or if I could have the debugger pause at the problem. Or if you have any other suggestions.
Thanks!
Edit 8/29/2021
I found two bugs in my code. Here are the actual bugs. It was a serious pain to track these down. I'm still looking for a tool or process to help the next time I make a silly mistake like this.
Bug #1:
I was using try/catch (shown in red) when I should have been using .catch() (shown in green). My try/catch did nothing. If there was an error sending the data, that would cause my program to crash.
Bug #2:
const promise = Deno.connect(options);
promise.catch(reportError);
promise.then(longRunningTask);
await someOtherPromise;
promise.then(connection => {
// We never get to here.
try {
connection.close();
} catch {
console.log("🙁");
}
});
// And we never get to here.
The code I've shown here was spread throughout a much longer program. I did not understand the rules regarding promises. The second .then() requires a second .catch().
Here was one of my attempts to solve this problem. I told VS code to break on all exceptions. It seems to ignore my request. I never got to a breakpoint, but the debug console shows that the program crashed because of an exception.

The noticeError method was not found. while using Coldbox and NewRelic for Error tracking

I'm just using NewRelic error trapping for my coldbox application. From OnException method, I'm just sending the error struct to log the error.
My code in onexception method
public function onException(event,rc,prc){
NewRelic.logError( prc.exception.getExceptionStruct());
}
The logerror() method resides in NewRelic.cfc and contains the following code
public boolean function logError(
required struct exception
) {
var cause = arguments.exception;
var params = {
error_id = createUUID(),
type: arguments.exception.type,
message: arguments.exception.message
};
writeDump(this.newRelic);
this.newRelic.noticeError(cause, params);abort;
return true;
}
So while error, I'm gettig the following error.
The noticeError method was not found.
You can see that, the noticeError() method is there in the object, but it is overloaded with arguments.
I'm using the same code for NewRelic error trapping in another coldfusion project without any frameworks.
Calling error.cfm through Cferror tag, and the code in error.cfm as follows
<cfset Application.newRelic.logError( variables.error )>
And in NewRelic.cfc, the logerror() method contains the same code as in the coldbox application. But it is logging errors in NewRelic without any issues.
This is the method I need to notice errors and log it in NewRelic.
noticeError(java.lang.Throwable, java.util.Map)
So I just thought to get the classname of the first argument Cause through the following code from both applications within logError() in NewRelic.cfc, to get the difference.
writeDump(cause.getClass().getName());
I'm getting
coldfusion.runtime.ExceptionScope for Coldbox application
and
coldfusion.runtime.UndefinedVariableException for normal coldfusion application
The cause argument is not throwable from coldbox application. So how to get the original error struct from coldbox application? and make it throwable to fix the noticeError method was not found issue.
The change in the underlying class happens when ColdBox duplicates the error object with CFML's duplicate() method. I doubt that ColdFusion behavior is documented anywhere, but I don't see an easy way to get around it right now other than creating your own instance of a java.langException and populating it with the details of the original error.
If you want to modify the ColdBox core code, this happens here:
https://github.com/ColdBox/coldbox-platform/blob/master/system/web/context/ExceptionBean.cfc#L43
I have entered this ticket for the ColdBox framework for us to review if we can stop duplicating the error object in future versions of the framework.
https://ortussolutions.atlassian.net/browse/COLDBOX-476
Update: Adam Cameron pointed out this ticket in the Adobe bug tracker that details this behavior in the engine. It was closed as "neverFix".
https://bugbase.adobe.com/index.cfm?event=bug&id=3976478

Try/catch issue - code not executing? AS3

private function rewriteQueue():void
{
try{
var file:File = File.applicationStorageDirectory.resolvePath( DATA_FILE_NAME );
file.deleteFile();
while (users.length) {
var aUser:Object = users.shift();
writeUser(aUser);
}
}catch (e:Error) {
}
}
In the above the while loop doesn't appear to execute. When I call the function in testing I have one item in the users array and it should be written to the file just deleted within the while, by calling writeUser(). However, once this is finished and I try and read the user from the file I can't - it's empty.
By placing the while outside the try/catch block it works fine.
I'm just wanting to know why.
EDIT: OK, I figured it out. The problem occurred when the file that was trying to be deleted didn't exist. That caused an error in deleteFile() - causing the while to not execute. Yeesh.
I know you already figured it out but for the sake of the community, please give the solution as an accepted answer in future so anyone browsing the site can tell if it's answered or not (this helps both experts and learners). The practice of answering your own questions is actually promoted quite strongly in the FAQ's.
The problem occurred when the file that was trying to be deleted
didn't exist. That caused an error in deleteFile() - causing the
while to not execute.
Also, the comment by LDMS is very valid. You shouldn't rely on Flash Professional's debug to tell you what's going on, using trace() can help a whole lot more.

AS3, Flash: Accessing error messages text in code

I'm working on some flash app. Now, to test customer side of it I can use Flash Player debugger version that will save logs and show error messages. When it's deployed on the customer side - they will have a regular Flash Player version which means I will have no access to error messages if errors will happen. So I would like to equip it with some tool that would capture all of my trace messages in code and errors text. As for trace messages that's fairly simple, I just override the function in my code so it sends a POST request with trace message to a logger server, but how can I get a hold of the error message? Is there a known approach to this or some trick that somebody can suggest?
You can install the debug version of flash as your browser's default (in Chrome, you must disable the built-in player), so if you wanted to test user experience and debug, this would be the ideal solution.
However, to answer your question: there's no method for universally catching all errors, and redirecting them (that I know of). You'd have to encapsulate problem code ahead of time with try...catch statements, and send the property back on catch. For example:
try {
this["foo"]();
} catch (e:Error) {
trace(e);
}
In the debug version, the traced value would be TypeError: Error #1006: value is not a function. And while the standard version will only output TypeError: Error #1006, (a notably less descriptive error), what we're missing is any reference to where the error occured. To get this, we need to use Error.getStackTrace() to see the call stack and the line where the error occurred. In debug, this outputs the following:
TypeError: Error #1006: value is not a function.
at Shell_fla::MainTimeline/init()[C:\Projects\shell.as:91
In the standard client, we get a dissapointing null. In short, you cannot get any valuable info from the client versions.
The best advice I can give is to write around your problem code with your own custom error reports. For example, catch IO errors and trace the file it failed to load, or if you're expecting an object.foo, first try if (object.hasOwnProperty("foo")) { // do something } else { trace("foo not found in " + object.name) }. Code defensively.
Cheers,
I've discovered this post on StackOverflow:
How to catch all exceptions in Flex?
It answers my question, strange that I haven't ran into it while I was googling prior to asking.

getting the stack trace of a flash application when running without the debugger

I'm trying to create a crash report for my application. Getting the stack trace is easy when the game is running with debug: it is included in the Error object that is created in the crash. but when running with no debug, this information is missing.
Is there any way to get this information?
You can use try-catch blocks in suspicious places of your app.
try {
ExternalInterface.call('conf', 4);
ExternalInterface.addCallback('transcodeReqAnswer', analyseTranscodeAnswer);
} catch(er:Error) {
debugTextField.text = er.getStackTrace();
}
If you are compiling in debug mode you have to pass the parameters to javascript through ExternalInterface. Then you should be able to see the stacktrace from the console output of your browser.
Example:
flash.system.Security.allowDomain(sourceDomain)
ExternalInterface.call("print", error.getStackTrace());
and in JavaScript there should be a function
function takeLog(string) {
console.log("stacktrace: " + string);
}
In non-debug mode the getStackTrace() function returns null.
More information in the official documentation,
ExternalInterface.call(),
getStackTrace()