I often waste a lot of time tracking down stupid bugs that are to do with passing the wrong kind of argument to a function. As you know, JavaScript is not strongly typed, and this leads to much sloppiness on my part. While writing RipDB - scriptDB emulator, which is a replication of the the old ScriptDB, I found I had no room for the kind of in flight changes i sometimes do to accommodate my own untidiness, so I decided to expand on Reporting file, function and line number in Apps Script, which is part of my cUseful library, to include a simple check at run time of arguments being passed versus what was expected. Here's how it works.This function
where
ExamplesBefore moving on to applying this to testing function arguments, let's look at some simple examples. Valid checks validateArgs (["abc",23,true,{"a":2}], ["string","number","boolean","object"] ); It can also detect JavaScript objects validateArgs ([new Date(), Date] , ["Date","function"] ); and Arrays validateArgs ([[1,2],[{"a":2},{"b":3}]], ["Array.number","Array.object"] ); Optional or multiple types validateArgs ([1,"w",false,new Date(),[3,4],[ "any","string","any","Array.any"] ); Missing arguments validateArgs( [1,2] , ["number","number","any"] ); Array validation for missing arguments validateArgs( [1,2,["a","b","c"]] , ["number","number","any.string"] ); Custom objects - from libraries or you create yourself validateArgs ( [myDb , results] , [DbAbstraction, Array.DbResults] ); and so on. Validating function argumentsOf course the real reason for this function is to validate arguments arriving in a function at run time against what was expected. One way is to repeat the function arguments. function yourFunction ( arga , argb ) { cUseful.validateArgs ([arga,argb] , ["string","Array.object"]); } The arguments parameter can be tweaked to look like an array and passed over, so a better way is to do this. cUseful.validateArgs ( Array.prototype.slice.call(arguments), [ "string" ,"Array.object"] ); That way, the only thing you have to maintain is the expected types array and validateArgs will complain if you have less valid types specified than arguments arriving. Throwing an errorBy default, it will throw an error when an argument is mismatched. However, passing the optFail parameter as false will not fail but return a results object like this, which shows the entire stack and what the problem was in the detail property. Even if you choose not to fail, this result will be written to the log file. You can access it like this var result = cUseful.validateArgs ( youArgs, yourChecks , false); if (!result.ok) { ...do something with the result object } You'll get this { "ok": false, "location": [ { "caller": "whereAmI", "line": "326", "file": "Code (cUseful)" }, { "caller": "report", "line": "582", "file": "Code (cUseful)" }, { "caller": "check", "line": "576", "file": "Code (cUseful)" }, { "caller": "validateArgs", "line": "529", "file": "Code (cUseful)" }, { "caller": "getMutationResults", "line": "30", "file": "RipDbMutation (cRipDB)" }, { "caller": "unknown", "line": "204", "file": "RipDb (cRipDB)" }, { "caller": "unknown", "line": "155", "file": "RipDb (cRipDB)" }, { "caller": "unknown", "line": "110", "file": "Code" }, { "caller": "unknown", "line": "1170", "file": "cDbAbstraction (cDbAbstraction)" }, { "caller": "unknown", "line": "1236", "file": "cDbAbstraction (cDbAbstraction)" }, { "caller": "unknown", "line": "258", "file": "Code (cNamedLock)" }, { "caller": "doGuts_", "line": "1230", "file": "cDbAbstraction (cDbAbstraction)" }, { "caller": "unknown", "line": "1124", "file": "cDbAbstraction (cDbAbstraction)" }, { "caller": "test", "line": "69", "file": "Code" }, { "caller": "unknown", "line": "54", "file": "Code" }, { "caller": "tall", "line": "52", "file": "Code" } ], "detail": { "index": 1, "arrayElement": -1, "type": "object", "expected": "object", "got": "undefined" } } The codeBest way to get this is to include the cUseful library, or you can find on GitHub or below. Many of the snippets in this section of the site are part of the cUseful library. You can find the details below. For more like this, see Google Apps Scripts snippets. Why not join our forum,follow the blog or follow me on twitter to ensure you get updates when they are available. You want to learn Google Apps Script?Learning Apps Script, (and transitioning from VBA) are covered comprehensively in my my book, Going Gas - from VBA to Apps script, available All formats are available now from O'Reilly,Amazon and all good bookshops. You can also read a preview on O'Reilly. If you prefer Video style learning I also have two courses available. also published by O'Reilly. |
Services > Desktop Liberation - the definitive resource for Google Apps Script and Microsoft Office automation > Google Apps Scripts snippets >