diff --git a/exec/load/acmev2.js b/exec/load/acmev2.js
index 00ed4272f41c61c46fe7b3a6e425575f12d81db5..2a7af2ab18233eedc9a5b7751c0b86f04ab859be 100644
--- a/exec/load/acmev2.js
+++ b/exec/load/acmev2.js
@@ -40,7 +40,7 @@ require("http.js", "HTTPRequest");
 function ACMEv2(opts)
 {
 	if (opts.key === undefined)
-		throw('Need "key"!');
+		throw new Error('Need "key"!');
 
 	this.key = opts.key;
 	this.key_id = opts.key_id;
@@ -70,9 +70,9 @@ ACMEv2.prototype.get_terms_of_service = function()
 {
 	var dir = this.get_directory();
 	if (dir.meta === undefined)
-		throw('No "meta" in directory!');
+		throw new Error('No "meta" in directory!');
 	if (dir.meta.termsOfService === undefined)
-		throw('No "termsOfService" in directory metadata');
+		throw new Error('No "termsOfService" in directory metadata');
 	return dir.meta.termsOfService;
 };
 
@@ -84,7 +84,7 @@ ACMEv2.prototype.get_directory = function()
 		this.log_headers();
 		if (this.ua.response_code != 200) {
 			log(LOG_DEBUG, ret);
-			throw("Error fetching directory");
+			throw new Error("Error fetching directory");
 		}
 		this.update_nonce();
 		this.directory = JSON.parse(ret);
@@ -98,12 +98,12 @@ ACMEv2.prototype.create_new_account = function(opts)
 
 	if (this.ua.response_code != 201 && this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("newAccount returned "+this.ua.response_code+", not a 200 or 201 status!");
+		throw new Error("newAccount returned "+this.ua.response_code+", not a 200 or 201 status!");
 	}
 
 	if (this.ua.response_headers_parsed.Location === undefined) {
 		log(LOG_DEBUG, this.ua.response_headers.join("\n"));
-		throw("No Location header in newAccount response.");
+		throw new Error("No Location header in newAccount response.");
 	}
 	this.key_id = this.ua.response_headers_parsed.Location[0];
 	return JSON.parse(ret);
@@ -117,7 +117,7 @@ ACMEv2.prototype.update_account = function(opts)
 
 	if (this.ua.response_code != 201 && this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("update_account returned "+this.ua.response_code+", not a 200 or 201 status!");
+		throw new Error("update_account returned "+this.ua.response_code+", not a 200 or 201 status!");
 	}
 	return JSON.parse(ret);
 };
@@ -132,17 +132,17 @@ ACMEv2.prototype.create_new_order = function(opts)
 	var ret;
 
 	if (opts.identifiers === undefined)
-		throw("create_new_order() requires an identifier in opts");
+		throw new Error("create_new_order() requires an identifier in opts");
 	ret = this.post('newOrder', opts);
 	if (this.ua.response_code != 201) {
 		log(LOG_DEBUG, ret);
-		throw("newOrder responded with "+this.ua.response_code+" not 201");
+		throw new Error("newOrder responded with "+this.ua.response_code+" not 201");
 	}
 	ret = JSON.parse(ret);
 
 	if (this.ua.response_headers_parsed.Location === undefined) {
 		log(LOG_DEBUG, this.ua.response_headers.join("\n"));
-		throw("No Location header in 201 response.");
+		throw new Error("No Location header in 201 response.");
 	}
 	ret.Location=this.ua.response_headers_parsed.Location[0];
 
@@ -156,7 +156,7 @@ ACMEv2.prototype.accept_challenge = function(challenge)
 	var ret = this.post_url(challenge.url, opts);
 	if (this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("accept_challenge did not return 200");
+		throw new Error("accept_challenge did not return 200");
 	}
 	return JSON.parse(ret);
 };
@@ -187,18 +187,18 @@ ACMEv2.prototype.finalize_order = function(order, csr)
 	var opts = {};
 
 	if (order === undefined)
-		throw("Missing order");
+		throw new Error("Missing order");
 	if (csr === undefined)
-		throw("Missing csr");
+		throw new Error("Missing csr");
 	if (typeof(csr) != 'object' || csr.export_cert === undefined)
-		throw("Invalid csr");
+		throw new Error("Invalid csr");
 	opts.csr = this.base64url(csr.export_cert(CryptCert.FORMAT.CERTIFICATE));
 
 	log(LOG_DEBUG, "Finalizing order.");
 	var ret = this.post_url(order.finalize, opts);
 	if (this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("finalize_order did not return 200");
+		throw new Error("finalize_order did not return 200");
 	}
 
 	return JSON.parse(ret);
@@ -208,13 +208,13 @@ ACMEv2.prototype.poll_order = function(order)
 {
 	var loc = order.Location;
 	if (loc === undefined)
-		throw("No order location!");
+		throw new Error("No order location!");
 	log(LOG_DEBUG, "Polling oder.");
 	var ret = this.ua.Get(loc);
 	this.log_headers();
 	if (this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("order poll did not return 200");
+		throw new Error("order poll did not return 200");
 	}
 	this.update_nonce();
 
@@ -245,7 +245,7 @@ ACMEv2.prototype.get_jwk = function(key)
 	var ret = {};
 
 	if (key === undefined)
-		throw("change_key() requires a new key.");
+		throw new Error("change_key() requires a new key.");
 	/* Create the inner object signed with old key */
 	switch(key.algo) {
 		case CryptContext.ALGO.RSA:
@@ -271,13 +271,13 @@ ACMEv2.prototype.get_jwk = function(key)
 					ret.shalen = 512;
 					break;
 				default:
-					throw("Unhandled ECC curve size "+key.keysize);
+					throw new Error("Unhandled ECC curve size "+key.keysize);
 			}
 			ret.jwk.x = key.public_key.x;
 			ret.jwk.y = key.public_key.y;
 			break;
 		default:
-			throw("Unknown algorithm in new key");
+			throw new Error("Unknown algorithm in new key");
 	}
 	return ret;
 };
@@ -290,7 +290,7 @@ ACMEv2.prototype.change_key = function(new_key)
 	var jwk;
 
 	if (new_key === undefined)
-		throw("change_key() requires a new key.");
+		throw new Error("change_key() requires a new key.");
 	/* Create the inner object signed with old key */
 	jwk = this.get_jwk(new_key);
 	inner.protected.alg = jwk.alg;
@@ -304,7 +304,7 @@ ACMEv2.prototype.change_key = function(new_key)
 	ret = this.post('keyChange', inner);
 	if (this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("keyChange did not return 200");
+		throw new Error("keyChange did not return 200");
 	}
 	this.key = new_key;
 	return JSON.parse(ret);
@@ -357,7 +357,7 @@ ACMEv2.prototype.revoke = function(cert, reason)
 	ret = this.post('revokeCert', opts);
 	if (this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("revokeCert did not return 200");
+		throw new Error("revokeCert did not return 200");
 	}
 	return;
 };
@@ -392,13 +392,13 @@ ACMEv2.prototype.create_pkcs7 = function(cert)
 ACMEv2.prototype.get_cert = function(order)
 {
 	if (order.certificate === undefined)
-		throw("Order has no certificate!");
+		throw new Error("Order has no certificate!");
 	log(LOG_DEBUG, "Getting certificate.");
 	var cert = this.ua.Get(order.certificate);
 	this.log_headers();
 	if (this.ua.response_code != 200) {
 		log(LOG_DEBUG, cert);
-		throw("get_cert request did not return 200");
+		throw new Error("get_cert request did not return 200");
 	}
 	this.update_nonce();
 
@@ -417,7 +417,7 @@ ACMEv2.prototype.post = function(link, data)
 		post_method = 'post_full_jwt';
 	url = this.get_directory()[link];
 	if (url === undefined)
-		throw('Unknown link name: "'+link+'"');
+		throw new Error('Unknown link name: "'+link+'"');
 	log(LOG_DEBUG, "Calling "+link+".");
 	return this.post_url(url, data, post_method);
 };
@@ -444,7 +444,7 @@ ACMEv2.prototype.get_authorization = function(url)
 	this.log_headers();
 	if (this.ua.response_code != 200) {
 		log(LOG_DEBUG, ret);
-		throw("get_authorization request did not return 200");
+		throw new Error("get_authorization request did not return 200");
 	}
 	this.update_nonce();
 
@@ -588,7 +588,7 @@ ACMEv2.prototype.post_url = function(url, data, post_method)
 			protected.alg = jwk.alg;
 			protected.kid = this.key_id;
 			if (protected.kid === undefined)
-				throw("No key_id available!");
+				throw new Error("No key_id available!");
 			break;
 		case 'post_full_jwt':
 			protected.nonce = this.get_nonce();
diff --git a/exec/load/binkp.js b/exec/load/binkp.js
index 979b78d8597dfd32901e9041d2cca21d6acaca93..068f486989d1f8b816992da6bd72e7d1a4aba8f3 100644
--- a/exec/load/binkp.js
+++ b/exec/load/binkp.js
@@ -412,7 +412,7 @@ BinkP.prototype.connect = function(addr, password, auth_cb, port, inet_host, tls
 	this.in_keys = undefined;
 	this.out_keys = undefined;
 	if (addr === undefined)
-		throw("No address specified!");
+		throw new Error("No address specified!");
 	addr = FIDO.parse_addr(addr, this.default_zone, this.default_domain);
 
 	if (!password)
@@ -1041,7 +1041,7 @@ BinkP.prototype.recvFrame = function(timeout)
 		ret = new this.Frame();
 		i = this.sock.recv(1, timeout);
 		if (i === null) {
-			log(LOG_INFO, "Error in recv() of first byte of packet header");
+			log(LOG_INFO, "Error in recv() of first byte of packet header, timeout = " + timeout);
 			this.sock.close();
 			this.sock = undefined;
 			return undefined;
diff --git a/exec/load/fido.js b/exec/load/fido.js
index 813f97ffc6a9f93d50ef7c4e5840e8ca638e5d76..0702b7fd64f6b9b11603e4e19709060739bd1f26 100644
--- a/exec/load/fido.js
+++ b/exec/load/fido.js
@@ -74,9 +74,9 @@ var FIDO = {
 				set: function(val) {
 					net = parseInt(val, 10);
 					if (typeof net !== 'number')
-						throw('net is not a number!');
+						throw new Error('net is not a number!');
 					if (net < 0 || net > 65535)
-						throw('net out of range');
+						throw new Error('net out of range');
 				}
 			},
 			"node": {
@@ -85,7 +85,7 @@ var FIDO = {
 				set: function(val) {
 					node = parseInt(val, 10);
 					if (typeof node !== 'number')
-						throw('node is not a number!');
+						throw new Error('node is not a number!');
 					if (node < 0 || node > 65535)
 						throw ('node out of range');
 				}
@@ -103,9 +103,9 @@ var FIDO = {
 					else
 						zone = parseInt(val, 10);
 					if (typeof zone !== 'number')
-						throw('zone is not a number!');
+						throw new Error('zone is not a number!');
 					if (zone < -1 || zone > 65535)
-						throw('zone out of range');
+						throw new Error('zone out of range');
 				}
 			},
 			"point": {
@@ -121,7 +121,7 @@ var FIDO = {
 					else
 						point = parseInt(val, 10);
 					if (typeof point !== 'number')
-						throw('point is not a number!');
+						throw new Error('point is not a number!');
 					if (point < 0 || point > 65535)
 						throw ('point out of range');
 				}
@@ -139,7 +139,7 @@ var FIDO = {
 					else
 						domain = val.toString().toLowerCase().substr(0, 8);
 					if (typeof domain !== 'string')
-						throw('domain is not a string');
+						throw new Error('domain is not a string');
 				}
 			}
 		});
@@ -153,7 +153,7 @@ var FIDO = {
 		if(addr)
 			m = addr.toString().match(/^(?:([0-9]+):)?([0-9]+)\/([0-9]+)(?:\.([0-9]+))?(?:@(.*))?$/);
 		if (!m)
-			throw('invalid address '+addr);
+			throw new Error('invalid address '+addr);
 		zone = m[1];
 		domain = m[5];
 		if (zone == undefined)
@@ -174,14 +174,14 @@ var FIDO = {
 		var ext;
 
 		if (default_zone === undefined)
-			throw("Default zone unspecified");
+			throw new Error("Default zone unspecified");
 		m = path.match(/(?:\.([0-9a-f]{3,4})[\/\\])?([0-9a-f]{4})([0-9a-f]{4})\.(...)(?:[\/\\]([0-9a-f]{8})\.(...))?$/i);
 		if (m === null)
-			throw("Invalid flo file path");
+			throw new Error("Invalid flo file path");
 		ext = m[4];
 		if (m[5] != null) {
 			if (m[4].toUpperCase() !== 'PNT')
-				throw("Invalid flo file path");
+				throw new Error("Invalid flo file path");
 			ext = m[6];
 		}
 		switch(ext.toLowerCase()) {
@@ -200,7 +200,7 @@ var FIDO = {
 			case 'try':
 				break;
 			default:
-				throw("Invalid flo file path");
+				throw new Error("Invalid flo file path");
 		}
 		zone = m[1];
 		if (zone == null)
@@ -230,12 +230,12 @@ var FIDO = {
 			domain = '';
 
 		if (!f.open("r"))
-			throw("Unable to open '"+f.name+"'.");
+			throw new Error("Unable to open '"+f.name+"'.");
 
 		// Validate first line...
 		var line = f.readln(2048);
 		if (line == undefined)
-			throw("Unable to read first line in '"+f.name+"'");
+			throw new Error("Unable to read first line in '"+f.name+"'");
 		var m;
 		if ((m=line.match(/^;A (.*) Nodelist for (.*) -- Day number ([0-9]+) : ([0-9]{5})$/)) !== null) {
 			ret.domain = m[1];
@@ -502,7 +502,7 @@ Object.defineProperties(FIDO.Addr.prototype, {
 
 			// TODO: Use default zone from system.fido_addr_list[0]?
 			if (this.zone === undefined)
-				throw('zone is undefined');
+				throw new Error('zone is undefined');
 
 			// TODO: These don't need to be loaded into different objects since we're doing 5D
 			if (FIDO.FTNDomains.nodeListFN[this.domain] !== undefined && file_exists(FIDO.FTNDomains.nodeListFN[this.domain])) {
@@ -530,7 +530,7 @@ Object.defineProperties(FIDO.Addr.prototype, {
 		get: function() {
 			// TODO: Use default zone from system.fido_addr_list[0]?
 			if (this.zone === undefined)
-				throw('zone is undefined');
+				throw new Error('zone is undefined');
 
 			// TODO: These don't need to be loaded into different objects since we're doing 5D
 			if (FIDO.FTNDomains.nodeListFN[this.domain] !== undefined && file_exists(FIDO.FTNDomains.nodeListFN[this.domain])) {
@@ -643,7 +643,7 @@ FIDO.Packet.prototype.setBin = function(offset, len, val) {
 	var str = '';
 
 	if (typeof(val) !== 'number')
-		throw('Invalid setBin value type');
+		throw new Error('Invalid setBin value type');
 	for (i=0; i<len; i++) {
 		str += ascii(val & 0xff);
 		val >>= 8;
diff --git a/exec/load/fido_syscfg.js b/exec/load/fido_syscfg.js
index 3214b8109e0a0c11b52aae3dd7ebf7d1203c1949..1cdbd251cb8851c24fe066a37ba52a9ce8ec0518 100644
--- a/exec/load/fido_syscfg.js
+++ b/exec/load/fido_syscfg.js
@@ -40,7 +40,7 @@ function SBBSEchoCfg ()
 
 	ecfg = new File(file_cfgname(system.ctrl_dir, 'sbbsecho.ini'));
 	if (!ecfg.open("r"))
-		throw("Unable to open '"+ecfg.name+"'");
+		throw new Error("Unable to open '"+ecfg.name+"'");
 
 	this.inbound = backslash(ecfg.iniGetValue(null, "Inbound", "../fido/nonsecure"));
 	if (this.inbound !== null)
diff --git a/exec/load/fidocfg.js b/exec/load/fidocfg.js
index 84d7c6508ac07b0acadbf7351d73f29923087791..706b1c2dc1fa95662ffefdbd3ba2e2d918a618a0 100644
--- a/exec/load/fidocfg.js
+++ b/exec/load/fidocfg.js
@@ -66,7 +66,7 @@ function TickITCfg() {
 	}
 
 	if (!tcfg.open("r"))
-		throw("Unable to open '"+tcfg.name+"'");
+		throw new Error("Unable to open '"+tcfg.name+"'");
 	this.gcfg = tcfg.iniGetObject();
 	lcprops(this.gcfg);
 	if (this.gcfg.handler !== undefined) {
diff --git a/exec/load/frame.js b/exec/load/frame.js
index 515407c650a65d303ed860662789de3afce132b1..b221323a250ec37824e6f6ee65b0f271c382dc87 100644
--- a/exec/load/frame.js
+++ b/exec/load/frame.js
@@ -189,14 +189,14 @@ Frame.prototype.__defineSetter__("child", function(frame) {
 	if(frame instanceof Frame)
 		this.__relations__.child.push(frame);
 	else
-		throw("child not an instance of Frame()");
+		throw new Error("child not an instance of Frame()");
 });
 Frame.prototype.__defineGetter__("attr", function() {
 	return this.__properties__.attr;
 });
 Frame.prototype.__defineSetter__("attr", function(attr) {
 	if(attr !== undefined && isNaN(attr))
-		throw("invalid attribute: " + attr);
+		throw new Error("invalid attribute: " + attr);
 	this.__properties__.attr = attr;
 });
 Frame.prototype.__defineGetter__("x", function() {
@@ -208,7 +208,7 @@ Frame.prototype.__defineSetter__("x", function(x) {
 	if(x == undefined)
 		return;
 	if(!this.__checkX__(x))
-		throw("invalid x coordinate: " + x);
+		throw new Error("invalid x coordinate: " + x);
 	this.__properties__.x = Number(x);
 });
 Frame.prototype.__defineGetter__("y", function() {
@@ -220,7 +220,7 @@ Frame.prototype.__defineSetter__("y", function(y) {
 	if(y == undefined)
 		return;
 	if(!this.__checkY__(y))
-		throw("invalid y coordinate: " + y);
+		throw new Error("invalid y coordinate: " + y);
 	this.__properties__.y = Number(y);
 });
 Frame.prototype.__defineGetter__("width", function() {
@@ -232,7 +232,7 @@ Frame.prototype.__defineSetter__("width", function(width) {
 	if(width == undefined)
 		return;
 	if(!this.__checkWidth__(this.x,Number(width)))
-		throw("invalid width: " + width);
+		throw new Error("invalid width: " + width);
 	this.__properties__.width = Number(width);
 });
 Frame.prototype.__defineGetter__("height", function() {
@@ -244,7 +244,7 @@ Frame.prototype.__defineSetter__("height", function(height) {
 	if(height == undefined)
 		return;
 	if(!this.__checkHeight__(this.y,Number(height)))
-		throw("invalid height: " + height);
+		throw new Error("invalid height: " + height);
 	this.__properties__.height = Number(height);
 });
 
@@ -289,7 +289,7 @@ Frame.prototype.__defineSetter__("checkbounds", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.checkbounds=bool;
 	else
-		throw("non-boolean checkbounds: " + bool);
+		throw new Error("non-boolean checkbounds: " + bool);
 });
 Frame.prototype.__defineGetter__("transparent", function() {
 	return this.__settings__.transparent;
@@ -298,7 +298,7 @@ Frame.prototype.__defineSetter__("transparent", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.transparent=bool;
 	else
-		throw("non-boolean transparent: " + bool);
+		throw new Error("non-boolean transparent: " + bool);
 });
 Frame.prototype.__defineGetter__("lf_strict", function() {
 	return this.__settings__.lf_strict;
@@ -307,7 +307,7 @@ Frame.prototype.__defineSetter__("lf_strict", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.lf_strict=bool;
 	else
-		throw("non-boolean lf_strict: " + bool);
+		throw new Error("non-boolean lf_strict: " + bool);
 });
 Frame.prototype.__defineGetter__("scrollbars", function() {
 	return this.__settings__.scrollbars;
@@ -316,7 +316,7 @@ Frame.prototype.__defineSetter__("scrollbars", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.scrollbars=bool;
 	else
-		throw("non-boolean scrollbars: " + bool);
+		throw new Error("non-boolean scrollbars: " + bool);
 });
 Frame.prototype.__defineGetter__("v_scroll", function() {
 	return this.__settings__.v_scroll;
@@ -325,7 +325,7 @@ Frame.prototype.__defineSetter__("v_scroll", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.v_scroll=bool;
 	else
-		throw("non-boolean v_scroll: " + bool);
+		throw new Error("non-boolean v_scroll: " + bool);
 });
 Frame.prototype.__defineGetter__("word_wrap", function() {
 	return this.__settings__.word_wrap;
@@ -334,7 +334,7 @@ Frame.prototype.__defineSetter__("word_wrap", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.word_wrap=bool;
 	else
-		throw("non-boolean word_wrap: " + bool);
+		throw new Error("non-boolean word_wrap: " + bool);
 });
 Frame.prototype.__defineGetter__("h_scroll", function() {
 	return this.__settings__.h_scroll;
@@ -343,7 +343,7 @@ Frame.prototype.__defineSetter__("h_scroll", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.h_scroll=bool;
 	else
-		throw("non-boolean h_scroll: " + bool);
+		throw new Error("non-boolean h_scroll: " + bool);
 });
 Frame.prototype.__defineGetter__("is_open",function() {
 	return this.__properties__.open;
@@ -355,7 +355,7 @@ Frame.prototype.__defineSetter__("atcodes", function(bool) {
 	if(typeof bool == "boolean")
 		this.__settings__.atcodes=bool;
 	else
-		throw("non-boolean atcode: " + bool);
+		throw new Error("non-boolean atcode: " + bool);
 });
 
 /* public methods */
@@ -367,7 +367,7 @@ Frame.prototype.getData = function(x,y,use_offset) {
 		py += this.__position__.offset.y;
 	}
 	// if(!this.__properties__.data[py] || !this.__properties__.data[py][px])
-		// throw("Frame.getData() - invalid coordinates: " + px + "," + py);
+		// throw new Error("Frame.getData() - invalid coordinates: " + px + "," + py);
 	if(!this.__properties__.data[py] || !this.__properties__.data[py][px])
 		return new Char();
 	return this.__properties__.data[py][px];
@@ -381,7 +381,7 @@ Frame.prototype.setData = function(x,y,ch,attr,use_offset) {
 	}
 	//I don't remember why I did this, but it was probably important at the time
 	//if(!this.__properties__.data[py] || !this.__properties__.data[py][px])
-		// throw("Frame.setData() - invalid coordinates: " + px + "," + py);
+		// throw new Error("Frame.setData() - invalid coordinates: " + px + "," + py);
 	if(!this.__properties__.data[py])
 		this.__properties__.data[py] = [];
 	if(!this.__properties__.data[py][px])
@@ -820,13 +820,13 @@ Frame.prototype.load = function(filename,width,height) {
 			this.putmsg(lines.shift() + "\r\n");
 		break;
 	default:
-		throw("unsupported filetype");
+		throw new Error("unsupported filetype");
 		break;
 	}
 }
 Frame.prototype.load_bin = function(contents, width, height, offset) {
     if(width == undefined || height == undefined)
-        throw("unknown graphic dimensions");
+        throw new Error("unknown graphic dimensions");
     if(offset == undefined) offset = 0;
     for(var y=0; y<height; y++) {
         for(var x=0; x<width; x++) {
@@ -1516,7 +1516,7 @@ Display.prototype.__defineSetter__("x", function(x) {
 	if(x == undefined)
 		this.__properties__.x = 1;
 	else if(isNaN(x))
-		throw("invalid x coordinate: " + x);
+		throw new Error("invalid x coordinate: " + x);
 	else
 		this.__properties__.x = Number(x);
 });
@@ -1527,7 +1527,7 @@ Display.prototype.__defineSetter__("y", function(y) {
 	if(y == undefined)
 		this.__properties__.y = 1;
 	else if(isNaN(y) || y < 1 || y > console.screen_rows)
-		throw("invalid y coordinate: " + y);
+		throw new Error("invalid y coordinate: " + y);
 	else
 		this.__properties__.y = Number(y);
 });
@@ -1538,7 +1538,7 @@ Display.prototype.__defineSetter__("width", function(width) {
 	if(width == undefined)
 		this.__properties__.width = console.screen_columns;
 	else if(isNaN(width) || (this.x + Number(width) - 1) > (console.screen_columns))
-		throw("invalid width: " + width);
+		throw new Error("invalid width: " + width);
 	else
 		this.__properties__.width = Number(width);
 });
@@ -1549,7 +1549,7 @@ Display.prototype.__defineSetter__("height", function(height) {
 	if(height == undefined)
 		this.__properties__.height = console.screen_rows;
 	else if(isNaN(height) || (this.y + Number(height) - 1) > (console.screen_rows))
-		throw("invalid height: " + height);
+		throw new Error("invalid height: " + height);
 	else
 		this.__properties__.height = Number(height);
 });
@@ -1763,7 +1763,7 @@ function Cursor(x,y,frame) {
 	if(frame instanceof Frame)
 		this.__properties__.frame = frame;
 	else
-		throw("the frame is not a frame");
+		throw new Error("the frame is not a frame");
 
 	this.x = x;
 	this.y = y;
@@ -1774,7 +1774,7 @@ Cursor.prototype.__defineGetter__("x", function() {
 });
 Cursor.prototype.__defineSetter__("x", function(x) {
 	if(isNaN(x))
-		throw("invalid x coordinate: " + x);
+		throw new Error("invalid x coordinate: " + x);
 	this.__properties__.x = x;
 });
 Cursor.prototype.__defineGetter__("y", function() {
@@ -1782,7 +1782,7 @@ Cursor.prototype.__defineGetter__("y", function() {
 });
 Cursor.prototype.__defineSetter__("y", function(y) {
 	if(isNaN(y))
-		throw("invalid y coordinate: " + y);
+		throw new Error("invalid y coordinate: " + y);
 	this.__properties__.y = y;
 });
 
@@ -1799,7 +1799,7 @@ function Offset(x,y,frame) {
 	if(frame instanceof Frame)
 		this.__properties__.frame = frame;
 	else
-		throw("the frame is not a frame");
+		throw new Error("the frame is not a frame");
 
 	this.x = x;
 	this.y = y;
@@ -1810,7 +1810,7 @@ Offset.prototype.__defineGetter__("x", function() {
 });
 Offset.prototype.__defineSetter__("x", function(x) {
 	if(x == undefined)
-		throw("invalid x offset: " + x);
+		throw new Error("invalid x offset: " + x);
 	else if(x < 0)
 		x = 0;
 	this.__properties__.x = x;
@@ -1820,7 +1820,7 @@ Offset.prototype.__defineGetter__("y", function() {
 });
 Offset.prototype.__defineSetter__("y", function(y) {
 	if(y == undefined)
-		throw("invalid y offset: " + y);
+		throw new Error("invalid y offset: " + y);
 	else if(y < 0)
 		y = 0;
 	this.__properties__.y = y;
diff --git a/exec/load/ftn_nodelist.js b/exec/load/ftn_nodelist.js
index 05d7578e6166f75915000c618d8c74891f114cc5..c1fa6016e263bffba970f070281946a7efaad2ee 100644
--- a/exec/load/ftn_nodelist.js
+++ b/exec/load/ftn_nodelist.js
@@ -63,12 +63,12 @@ function NodeList(filename, warn)
 	});
 
 	if (!f.open("r"))
-		throw("Unable to open '"+f.name+"'.");
+		throw new Error("Unable to open '"+f.name+"'.");
 
 	// Validate first line...
 	var line = f.readln(2048);
 	if (line == undefined)
-		throw("Unable to read first line in '"+f.name+"'");
+		throw new Error("Unable to read first line in '"+f.name+"'");
 	var m;
 	if ((m=line.match(/^;A (.*) Nodelist for (.*) -- Day number ([0-9]+) : ([0-9]{5})$/)) !== null) {
 		this.domain = m[1];
diff --git a/exec/load/ftp.js b/exec/load/ftp.js
index f3fcbdcec91e35ae9acfead849194308dc11d43f..d8d70a165aaca304ee00ecc45047728ac1f15a7d 100644
--- a/exec/load/ftp.js
+++ b/exec/load/ftp.js
@@ -7,7 +7,7 @@ function FTP(host, user, pass, port, dport, bindhost, account)
 	var ret;
 
 	if (host === undefined)
-		throw("No hostname specified");
+		throw new Error("No hostname specified");
 	
 	this.revision = "JSFTP v" + "$Revision: 1.23 $".split(' ')[1];
 
@@ -40,19 +40,19 @@ function FTP(host, user, pass, port, dport, bindhost, account)
 	}
 	if (parseInt(response, 10) !== 220) {
 		this.socket.close();
-		throw("Invalid response from server: " + response);
+		throw new Error("Invalid response from server: " + response);
 	}
 	ret = parseInt(response = this.cmd("USER "+this.user, true), 10)
 	if (ret === 331)
 		ret = parseInt(response = this.cmd("PASS "+this.pass, true), 10);
 	if (ret === 332) {
 		if (this.account === undefined)
-			throw("Account required");
+			throw new Error("Account required");
 		ret = parseInt(response = this.cmd("ACCT "+this.account, true), 10);
 	}
 	if (ret !== 230 && ret != 202) {
 		this.socket.close();
-		throw("Login failed: " + response);
+		throw new Error("Login failed: " + response);
 	}
 	this.ascii = false;
 	this.passive = true;
@@ -298,7 +298,7 @@ FTP.prototype.do_sendfile = function(src, data_socket)
 	var f = new File(src);
 	if (!f.open("rb")) {
 		data_socket.close();
-		throw("Error " + f.error + " opening file '" + f.name + "'");
+		throw new Error("Error " + f.error + " opening file '" + f.name + "'");
 	}
 
 	do {
@@ -315,7 +315,7 @@ FTP.prototype.do_sendfile = function(src, data_socket)
 
 	rstr = this.cmd(undefined, true);
 	if (parseInt(rstr, 10) !== 226) {
-		throw("Data connection not closed: "+rstr);
+		throw new Error("Data connection not closed: "+rstr);
 	}
 	if (!error)
 		log(LOG_DEBUG, "Sent "+total+" bytes.");
@@ -333,7 +333,7 @@ FTP.prototype.cmd = function(cmd, needresp)
 	var done = false;
 
 	if (!this.socket.is_connected)
-		throw("Socket disconnected");
+		throw new Error("Socket disconnected");
 
 	if (cmd !== undefined) {
 		while (this.socket.data_waiting) {
@@ -343,7 +343,7 @@ FTP.prototype.cmd = function(cmd, needresp)
 		cmdline = cmd.replace(/\xff/g, "\xff\xff") + '\r\n';
 		log(LOG_DEBUG, "CMD: '"+cmd+"'");
 		if (this.socket.send(cmdline) != cmdline.length)
-			throw("Error " + this.socket.error + " sending command: '" + cmd + "'");
+			throw new Error("Error " + this.socket.error + " sending command: '" + cmd + "'");
 	}
 
 	if (needresp === true) {
@@ -355,7 +355,7 @@ FTP.prototype.cmd = function(cmd, needresp)
 				m = rd.match(/^([0-9]{3})([- ])/);
 				if (rsp === undefined) {
 					if (m === null) {
-						throw("Invalid response: "+rd);
+						throw new Error("Invalid response: "+rd);
 					}
 					rsp = m[1];
 					if (m[2] === ' ')
@@ -373,9 +373,9 @@ FTP.prototype.cmd = function(cmd, needresp)
 			}
 			else {
 				if(cmd)
-					throw("recvline timeout waiting for response to command: '" + cmd + "'");
+					throw new Error("recvline timeout waiting for response to command: '" + cmd + "'");
 				else
-					throw("recvline timeout waiting for additional response");
+					throw new Error("recvline timeout waiting for additional response");
 			}
 		} while(this.socket.is_connected && !done);
 		return ret;
@@ -399,7 +399,7 @@ FTP.prototype.data_socket = function(cmd)
 	else
 		rstr = this.cmd("TYPE I", true);
 	if (parseInt(rstr, 10) !== 200)
-		throw("Unable to create data socket: " + rstr);
+		throw new Error("Unable to create data socket: " + rstr);
 
 	ip6 = this.socket.local_ip_address.indexOf(':') !== -1;
 	if (this.passive) {
@@ -407,20 +407,20 @@ FTP.prototype.data_socket = function(cmd)
 		if (ip6) {
 			rstr = this.cmd("EPSV", true);
 			if (parseInt(rstr, 10) !== 229)
-				throw("EPSV Failed: " + rstr);
+				throw new Error("EPSV Failed: " + rstr);
 			m = rstr.match(/\(\|\|\|([0-9]+)\|\)/);
 			if (m === null)
-				throw("Unable to parse EPSV reply: " + rstr);
+				throw new Error("Unable to parse EPSV reply: " + rstr);
 			rhost = this.host;
 			rport = parseInt(m[1], 10);
 		}
 		else {
 			rstr = this.cmd("PASV", true);
 			if (parseInt(rstr, 10) !== 227)
-				throw("PASV Failed: " + rstr);
+				throw new Error("PASV Failed: " + rstr);
 			m = rstr.match(/\(([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+)\)/);
 			if (m === null)
-				throw("Unable to parse PASV reply: " + rstr);
+				throw new Error("Unable to parse PASV reply: " + rstr);
 			rhost = m[1] + '.' + m[2] + '.' + m[3] + '.' + m[4];
 			rport = (parseInt(m[5], 10) << 8) | parseInt(m[6], 10);
 		}
@@ -443,11 +443,11 @@ FTP.prototype.data_socket = function(cmd)
 			}
 		} catch(e) {
 			ds.close();
-			throw(e);
+			throw new Error(e);
 		}
 		if (parseInt(rstr, 10) !== 200) {
 			ds.close();
-			throw("EPRT/PORT rejected: " + rstr);
+			throw new Error("EPRT/PORT rejected: " + rstr);
 		}
 	}
 
@@ -461,14 +461,14 @@ FTP.prototype.data_socket = function(cmd)
 			// Fall-through
 		default:
 			ds.close();
-			throw(cmd+" failed: " + rstr);
+			throw new Error(cmd+" failed: " + rstr);
 	}
 
 	if (!this.passive) {
 		selret = socket_select([ds], this.timeout);
 		if (selret === null || selret.length === 0) {
 			ds.close();
-			throw("Timeout waiting for remote to connect");
+			throw new Error("Timeout waiting for remote to connect");
 		}
 		ts = ds.accept();
 		ds.close();
@@ -496,7 +496,7 @@ FTP.prototype.do_get = function(cmd, dest)
 		f = new File(dest);
 		if (!f.open("wb")) {
 			data_socket.close();
-			throw("Error " + f.error + " opening file '" + f.name + "'");
+			throw new Error("Error " + f.error + " opening file '" + f.name + "'");
 		}
 	}
 
@@ -510,14 +510,14 @@ FTP.prototype.do_get = function(cmd, dest)
 				f.write(rbuf);
 		}
 		else {
-			throw("recv timeout");
+			throw new Error("recv timeout");
 		}
 	} while(data_socket.is_connected && this.socket.is_connected);
 	data_socket.close();
 	if (f !== undefined)
 		f.close();
 	if (parseInt(this.cmd(undefined, true), 10) !== 226)
-		throw("Data connection not closed");
+		throw new Error("Data connection not closed");
 	log(LOG_DEBUG, "Received "+total+" bytes.");
 	if (dest === undefined)
 		return ret;
diff --git a/exec/load/graphic.js b/exec/load/graphic.js
index f5b8acbbf059a1125992a88b7df4a55f59423ef5..4e895b122a67c686298cb8928fb0910249ea4ae1 100644
--- a/exec/load/graphic.js
+++ b/exec/load/graphic.js
@@ -690,7 +690,7 @@ Graphic.prototype.load = function(filename, offset)
 	var l;
 
 	if(!file_type)
-		throw("unsupported file type: " + filename);
+		throw new Error("unsupported file type: " + filename);
 
 	switch(file_type.substr(1).toUpperCase()) {
 	case "ANS":
@@ -716,7 +716,7 @@ Graphic.prototype.load = function(filename, offset)
 			this.putmsg(undefined,undefined,l,true);
 		break;
 	default:
-		throw("unsupported file type: " + filename);
+		throw new Error("unsupported file type: " + filename);
 	}
 	return(true);
 };
diff --git a/exec/load/http.js b/exec/load/http.js
index 0af0a1970649dd6ff41b16157bd73e85cff812c9..40d5049bd86273712e4fc4a0dd3c910dcf31190c 100644
--- a/exec/load/http.js
+++ b/exec/load/http.js
@@ -114,39 +114,39 @@ HTTPRequest.prototype.SendRequest=function() {
 	port = this.url.port?this.url.port:(this.url.scheme=='http'?80:443);
 	if (js.global.ConnectedSocket != undefined) {
 		if ((this.sock = new ConnectedSocket(this.url.host, port)) == null)
-			throw(format("Unable to connect to %s:%u", this.url.host, this.url.port));
+			throw new Error(format("Unable to connect to %s:%u", this.url.host, this.url.port));
 	}
 	else {
 		if((this.sock=new Socket(SOCK_STREAM))==null)
-			throw("Unable to create socket");
+			throw new Error("Unable to create socket");
 		if(!this.sock.connect(this.url.host, port)) {
 			this.sock.close();
-			throw(format("Unable to connect to %s:%u", this.url.host, this.url.port));
+			throw new Error(format("Unable to connect to %s:%u", this.url.host, this.url.port));
 		}
 	}
 	if(this.url.scheme=='https')
 		this.sock.ssl_session=true;
 	if(!do_send(this.sock, this.request+"\r\n"))
-		throw("Unable to send request: " + this.request);
+		throw new Error("Unable to send request: " + this.request);
 	for(i in this.request_headers) {
 		if(!do_send(this.sock, this.request_headers[i]+"\r\n"))
-			throw("Unable to send headers");
+			throw new Error("Unable to send headers");
 	}
 	if(!do_send(this.sock, "\r\n"))
-		throw("Unable to terminate headers");
+		throw new Error("Unable to terminate headers");
 	if(this.body != undefined) {
 		if(!do_send(this.sock, this.body))
-			throw("Unable to send body");
+			throw new Error("Unable to send body");
 	}
 };
 
 HTTPRequest.prototype.ReadStatus=function() {
 	this.status_line=this.sock.recvline(4096);
 	if(this.status_line==null)
-		throw("Unable to read status");
+		throw new Error("Unable to read status");
 	var m = this.status_line.match(/^HTTP\/[0-9]+\.[0-9]+ ([0-9]{3})/);
 	if (m === null)
-		throw("Unable to parse status line '"+this.status_line+"'");
+		throw new Error("Unable to parse status line '"+this.status_line+"'");
 	this.response_code = parseInt(m[1], 10);
 };
 
@@ -159,7 +159,7 @@ HTTPRequest.prototype.ReadHeaders=function() {
 	for(;;) {
 		header=this.sock.recvline(4096, 120);
 		if(header==null)
-			throw("Unable to receive headers");
+			throw new Error("Unable to receive headers");
 		if(header=='')
 			return;
 		this.response_headers.push(header);
diff --git a/exec/load/json-chat.js b/exec/load/json-chat.js
index 1fcf59391988804e4dcf3064e1a77b41bc92014d..a71373ad7468ef559987a6010d2b2716861c7e20 100644
--- a/exec/load/json-chat.js
+++ b/exec/load/json-chat.js
@@ -38,7 +38,7 @@ function JSONChat(usernum,jsonclient,host,port) {
 			
 		if(!this.client) {
 			if(!host || isNaN(port))
-				throw("invalid client arguments");
+				throw new Error("invalid client arguments");
 			this.client = new JSONClient(host,port);
 		}
 		if(!this.client.connect()) {
@@ -48,7 +48,7 @@ function JSONChat(usernum,jsonclient,host,port) {
 		if(this.nick)
 			this.client.subscribe("chat","channels." + this.nick.name + ".messages");
 		else
-			throw("invalid user number");
+			throw new Error("invalid user number");
 		for(var c in this.channels) 
 			this.join(c.name);
 		return true;
diff --git a/exec/load/mouse_getkey.js b/exec/load/mouse_getkey.js
index 890cb093d28aba456884d88536ac27590e9f5144..6a368f8274291210c225ed67ae1206ee1cee9deb 100644
--- a/exec/load/mouse_getkey.js
+++ b/exec/load/mouse_getkey.js
@@ -18,7 +18,7 @@ function mouse_getkey(mode, timeout, enabled)
 	var safe_mode = mode & ~(K_UPPER|K_UPRLWR|K_NUMBER|K_ALPHA|K_NOEXASC);
 
 	if (safe_mode != mode) {
-		throw("Invalid mode "+mode+" for mouse_getkey()");
+		throw new Error("Invalid mode "+mode+" for mouse_getkey()");
 	}
 	
 	function mouse_enable(enable)
diff --git a/exec/load/recordfile.js b/exec/load/recordfile.js
index b788647c199b02de9b5c2e79f7d12fd1d0753317..52195269144ddd4ac6c07b619989837dc9055591 100644
--- a/exec/load/recordfile.js
+++ b/exec/load/recordfile.js
@@ -116,7 +116,7 @@ RecordFileRecord.prototype.flushRead = function(keeplocked)
 		}
 		this.parent.file.close();
 		if (!this.parent.file.open('rb+', true, this.parent.RecordLength)) {
-			throw('Unable to re-open '+this.parent.file.name);
+			throw new Error('Unable to re-open '+this.parent.file.name);
 		}
 		if (locked) {
 			this.lock();
diff --git a/exec/load/require.js b/exec/load/require.js
index 53b486b99910871a96d04019a6d0e41ea0f983ea..bcfbc2e25fd1ee1a5183b209b2f2dc1438e5d891 100644
--- a/exec/load/require.js
+++ b/exec/load/require.js
@@ -3,7 +3,7 @@ if (eval('typeof('+argv[2]+') !== "undefined" ? true : false'))
 	js.global.require_module_file = 'dummy.js';
 load(js.global.require_module_file);
 if (eval('typeof('+argv[2]+') == "undefined"'))
-	throw("ERROR: load()ing "+argv[1]+" didn't define symbol \""+argv[2]+"\"");
+	throw new Error("ERROR: load()ing "+argv[1]+" didn't define symbol \""+argv[2]+"\"");
 if (argv[0] === 'undefined') {
 	Object.defineProperties(this, {
 		"argv": {
diff --git a/exec/load/sprite.js b/exec/load/sprite.js
index dc9a1f8d7c56508797da5232ed21b6614b3b8195..da160c1e87432ee8414a8792c65cd1140729a706 100644
--- a/exec/load/sprite.js
+++ b/exec/load/sprite.js
@@ -436,10 +436,10 @@ Sprite.Aerial = function(fileName, parentFrame, x, y, bearing, position) {
 	if(!file_exists(fileName + ".ini"))
 		fileName = js.exec_dir + "sprites/" + fileName;
 	if(!file_exists(fileName + ".ini")) {
-		throw("Sprite file missing: " + fileName + ".ini");
+		throw new Error("Sprite file missing: " + fileName + ".ini");
 	}
 	if(!file_exists(fileName + ".bin")) {
-		throw("Sprite file missing: " + fileName + ".bin");
+		throw new Error("Sprite file missing: " + fileName + ".bin");
 	}
 
 	this.x = x;
@@ -958,10 +958,10 @@ Sprite.Profile = function(fileName, parentFrame, x, y, bearing, position) {
 	if(!file_exists(fileName + ".ini"))
 		fileName = js.exec_dir + "sprites/" + fileName;
 	if(!file_exists(fileName + ".ini")) {
-		throw("Sprite file missing: " + fileName + ".ini");
+		throw new Error("Sprite file missing: " + fileName + ".ini");
 	}
 	if(!file_exists(fileName + ".bin")) {
-		throw("Sprite file missing: " + fileName + ".bin");
+		throw new Error("Sprite file missing: " + fileName + ".bin");
 	}
 
 	this.x = x;
diff --git a/exec/load/tree.js b/exec/load/tree.js
index e3ffbcaecb76c6b76f2f2494d58c999b03cf945a..44ca5cf8882c8735bb8a7ea6aa301dfc9823eb66 100644
--- a/exec/load/tree.js
+++ b/exec/load/tree.js
@@ -204,7 +204,7 @@ Tree.prototype.__defineSetter__("frame",function(frame) {
 		return true;
 	}
 	else {
-		throw("frame parameter must be a Frame() object");
+		throw new Error("frame parameter must be a Frame() object");
 	}
 });
 Tree.prototype.__defineGetter__("items",function() {
@@ -216,7 +216,7 @@ Tree.prototype.__defineSetter__("items",function(items) {
 		return true;
 	}
 	else {
-		throw("items parameter must be an array");
+		throw new Error("items parameter must be an array");
 	}
 });
 Tree.prototype.__defineGetter__("parent",function() {