JSON.parse throws on garbage — and webhooks, Script Properties, and CacheService strings go garbage more often than we’d like. safeJsonParse(text, fallback) returns the fallback instead of blowing up; optional onError lets you log without changing the happy path.
What you'll need
- Any Apps Script that reads JSON from Properties, Cache, webhooks, or Drive text
- A sensible fallback (object, array, or
null) - Optional: a logger / Log sheet for parse failures
How to use this snippet
/**
* Parse JSON without throwing. Returns fallback on null/empty/invalid input.
* @param {string} text
* @param {*} fallback value when parse fails or text is empty
* @param {function(Error, string)=} onError optional side-effect (log, alert)
* @return {*}
*/
function safeJsonParse(text, fallback, onError) {
if (text == null || text === '') return fallback;
try {
return JSON.parse(text);
} catch (err) {
if (typeof onError === 'function') {
try {
onError(err, text);
} catch (ignore) {
// never let logging break the caller
}
}
return fallback;
}
}
Example
function loadConfig_() {
var raw = PropertiesService.getScriptProperties().getProperty('config');
return safeJsonParse(raw, { mode: 'safe', limit: 100 }, function (err, text) {
console.warn('config JSON bad:', err.message, String(text).substring(0, 80));
});
}
function doPost(e) {
var body = (e && e.postData && e.postData.contents) || '';
var payload = safeJsonParse(body, null);
if (!payload) {
return ContentService.createTextOutput('bad json').setMimeType(ContentService.MimeType.TEXT);
}
// … handle payload …
}
Tips:
- Prefer a typed fallback (
{}/[]) so callers don’t null-check every field. - Truncate
textinonError— don’t log megabyte webhook bodies. - Pair with checkpoints and Cache tokens that round-trip JSON.
JSON.parse('null')returnsnullsuccessfully — if that’s invalid for you, validate shape after parse.
Tip: NitroGAS Co-Pilot can wrap your Properties / doPost reads with safeJsonParse and a tiny onError logger — soft assist, you own the fallback shape.
Happy Coding!
