Last active
August 27, 2019 09:57
Cookbook Recipe: Add A Crash Reporter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Generic development-oriented crash report service | |
* | |
* @author Tony Smith (@smittytone) | |
* @licence MIT | |
* @version 1.0.0 | |
*/ | |
crashReporter <- { | |
/** | |
* Reference to a function responsible for sending notifications | |
* | |
* @property | |
*/ | |
"messenger" : null, | |
/** | |
* Relay an error received from the device (or the agent itself) | |
* | |
* @param {string} error - The error message to relay | |
*/ | |
"report" : function(error) { | |
// Prepare the error report text | |
local report = "*ERROR REPORT*\n*TIME* " + crashReporter.timestamp() + "\n"; | |
report += "*ERROR* " + error + "\n"; | |
report += "*DEVICE* " + imp.configparams.deviceid + "\n"; | |
report += "*GROUP* " + __EI.DEVICEGROUP_NAME + "\n"; | |
report += "*PRODUCT* " + __EI.PRODUCT_NAME; | |
// Send the report text via the chosen messenger object | |
crashReporter.messenger(report); | |
}, | |
/** | |
* Initilize the service | |
* | |
* @param {function} messengerFunction - The function to send error messages (agent only) | |
*/ | |
"init" : function(messengerFunction = null) { | |
// Register the agent's device message handler on the agent | |
local isAgent = (imp.environment() == 2); | |
// Set up the agenrt and check the messenger object | |
if (isAgent) { | |
if (messengerFunction == null || typeof messengerFunction != "function") | |
throw("crashReporter.init() requires a messenger function"); | |
crashReporter.messenger = messengerFunction; | |
device.on("crash.reporter.relay.debug.error", crashReporter.report); | |
} | |
// Register the onunhandled callback | |
imp.onunhandledexception(function(error) { | |
// Only operate in DEBUG mode, ie. with development device groups | |
if (__EI.DEVICEGROUP_TYPE == "development") { | |
if (isAgent) { | |
// Running on the agent: just relay the error | |
crashReporter.report(error); | |
} else { | |
// Running on the device: send the error to the agent | |
agent.send("crash.reporter.relay.debug.error", error); | |
server.flush(10); | |
} | |
} | |
// Squirrel VM will restart at this point | |
}.bindenv(this)); | |
}, | |
/** | |
* Returns the current date as a formatted string | |
* | |
* @returns {string} The formatted date | |
*/ | |
"timestamp": function() { | |
local time = date(); | |
local bst = false; | |
if ("utilities" in getroottable()) bst = utilities.isBST(); | |
time.hour += (bst ? 1 : 0); | |
if (time.hour > 23) time.hour -= 24; | |
local z = bst ? "+01:00" : "UTC"; | |
return format("%04d-%02d-%02d %02d:%02d:%02d %s", time.year, time.month + 1, time.day, time.hour, time.min, time.sec, z); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Basic Slack message poster using the Incoming Webhook | |
* | |
* @author Tony Smith (@smittytone) | |
* @licence MIT | |
* @version 1.0.1 | |
* | |
* @class | |
*/ | |
class SimpleSlack { | |
static VERSION = "1.0.1"; | |
static BASE = "https://hooks.slack.com/services/" | |
_key = null; | |
/** | |
* Instantiate the class | |
* | |
* @param {string} webook - The string provided by Slack for a new webhook, eg. "T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX" | |
* | |
* @returns {instance} this | |
*/ | |
constructor(webhook = null) { | |
if (webhook == null || (typeof webhook != "blob" && typeof webhook != "string")) throw "SimpleSlack() requires a valid webhook path"; | |
_key = typeof webhook == "string" ? webhook : webhook.tostring(); | |
} | |
/** | |
* Post a message to Slack asynnchronously | |
* | |
* @param {string} message - The message to post | |
*/ | |
function post(message = "") { | |
// Check that the incoming message is good to go - report an error if it is not | |
if (message == null || message.len() == 0 || typeof message != "string") { | |
server.error("Slack.post() passed in invalid message string"); | |
return; | |
} | |
// Prepare and send the message to Slack asynchronously | |
local body = {"text":message,"mrkdwn":true}; | |
local req = http.post(BASE + _key, {"Content-type":"application/json"}, http.jsonencode(body)); | |
req.sendasync(_done); | |
} | |
/** | |
* Handle any response from Slack. Currently just logs errors | |
* | |
* @param {table} rsp - The response from Slack | |
* | |
* @private | |
*/ | |
function _done(rsp) { | |
if (rsp.statuscode != 200) { | |
server.error("Could not post message (code: " + rsp.statuscode + ")"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment