Skip to content

Instantly share code, notes, and snippets.

@ElectricImpSampleCode
Last active August 27, 2019 09:57
Show Gist options
  • Save ElectricImpSampleCode/5e3d82f0ecd9d4a58b1f83c11f9f5496 to your computer and use it in GitHub Desktop.
Save ElectricImpSampleCode/5e3d82f0ecd9d4a58b1f83c11f9f5496 to your computer and use it in GitHub Desktop.
Cookbook Recipe: Add A Crash Reporter
/**
* 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);
}
};
/**
* 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