Bug 903741: Use new DOMError approach in PeerConnection to get error messages out + unittests r=jesup

This commit is contained in:
Jan-Ivar Bruaroey 2013-09-06 15:29:29 -04:00
parent 5c73c402f3
commit d22db0e6de
3 changed files with 47 additions and 37 deletions

View File

@ -273,7 +273,8 @@ RTCPeerConnection.prototype = {
this._mustValidateRTCConfiguration(rtcConfig, this._mustValidateRTCConfiguration(rtcConfig,
"RTCPeerConnection constructor passed invalid RTCConfiguration"); "RTCPeerConnection constructor passed invalid RTCConfiguration");
if (_globalPCList._networkdown) { if (_globalPCList._networkdown) {
throw new Components.Exception("Can't create RTCPeerConnections when the network is down"); throw new this._win.DOMError("",
"Can't create RTCPeerConnections when the network is down");
} }
this.makeGetterSetterEH("onaddstream"); this.makeGetterSetterEH("onaddstream");
@ -305,7 +306,8 @@ RTCPeerConnection.prototype = {
_getPC: function() { _getPC: function() {
if (!this._pc) { if (!this._pc) {
throw new Components.Exception("RTCPeerConnection is gone (did you enter Offline mode?)"); throw new this._win.DOMError("",
"RTCPeerConnection is gone (did you enter Offline mode?)");
} }
return this._pc; return this._pc;
}, },
@ -423,41 +425,40 @@ RTCPeerConnection.prototype = {
// Parse-aid: Testing for pilot error of missing outer block avoids // Parse-aid: Testing for pilot error of missing outer block avoids
// otherwise silent no-op since both mandatory and optional are optional // otherwise silent no-op since both mandatory and optional are optional
if (!isObject(constraints) || Array.isArray(constraints)) { if (!isObject(constraints) || Array.isArray(constraints)) {
throw new Components.Exception(errorMsg); throw new this._win.DOMError("", errorMsg);
} }
if (constraints.mandatory) { if (constraints.mandatory) {
// Testing for pilot error of using [] on mandatory here throws nicer msg // Testing for pilot error of using [] on mandatory here throws nicer msg
// (arrays would throw in loop below regardless but with more cryptic msg) // (arrays would throw in loop below regardless but with more cryptic msg)
if (!isObject(constraints.mandatory) || Array.isArray(constraints.mandatory)) { if (!isObject(constraints.mandatory) || Array.isArray(constraints.mandatory)) {
throw new Components.Exception(errorMsg + " - malformed mandatory constraints"); throw new this._win.DOMError("",
errorMsg + " - malformed mandatory constraints");
} }
for (let constraint in constraints.mandatory) { for (let constraint in constraints.mandatory) {
if (!(constraint in SUPPORTED_CONSTRAINTS) && if (!(constraint in SUPPORTED_CONSTRAINTS) &&
constraints.mandatory.hasOwnProperty(constraint)) { constraints.mandatory.hasOwnProperty(constraint)) {
throw new Components.Exception(errorMsg + " - " + throw new this._win.DOMError("", errorMsg + " - " +
((constraint in OTHER_KNOWN_CONSTRAINTS)? ((constraint in OTHER_KNOWN_CONSTRAINTS)? "unsupported" : "unknown") +
"unsupported" : "unknown") + " mandatory constraint: " + constraint);
" mandatory constraint: " + constraint);
} }
} }
} }
if (constraints.optional) { if (constraints.optional) {
if (!isArraylike(constraints.optional)) { if (!isArraylike(constraints.optional)) {
throw new Components.Exception(errorMsg + throw new this._win.DOMError("",
" - malformed optional constraint array"); errorMsg + " - malformed optional constraint array");
} }
let len = constraints.optional.length; let len = constraints.optional.length;
for (let i = 0; i < len; i += 1) { for (let i = 0; i < len; i += 1) {
if (!isObject(constraints.optional[i])) { if (!isObject(constraints.optional[i])) {
throw new Components.Exception(errorMsg + throw new this._win.DOMError("", errorMsg +
" - malformed optional constraint: " + " - malformed optional constraint: " + constraints.optional[i]);
constraints.optional[i]);
} }
let constraints_per_entry = 0; let constraints_per_entry = 0;
for (let constraint in constraints.optional[i]) { for (let constraint in constraints.optional[i]) {
if (constraints.optional[i].hasOwnProperty(constraint)) { if (constraints.optional[i].hasOwnProperty(constraint)) {
if (constraints_per_entry) { if (constraints_per_entry) {
throw new Components.Exception(errorMsg + throw new this._win.DOMError("", errorMsg +
" - optional constraint must be single key/value pair"); " - optional constraint must be single key/value pair");
} }
constraints_per_entry += 1; constraints_per_entry += 1;
@ -473,7 +474,7 @@ RTCPeerConnection.prototype = {
// spec. See Bug 831756. // spec. See Bug 831756.
_checkClosed: function() { _checkClosed: function() {
if (this._closed) { if (this._closed) {
throw new Components.Exception("Peer connection is closed"); throw new this._win.DOMError("", "Peer connection is closed");
} }
}, },
@ -629,11 +630,10 @@ RTCPeerConnection.prototype = {
type = Ci.IPeerConnection.kActionAnswer; type = Ci.IPeerConnection.kActionAnswer;
break; break;
case "pranswer": case "pranswer":
throw new Components.Exception("pranswer not yet implemented", throw new this._win.DOMError("", "pranswer not yet implemented");
Cr.NS_ERROR_NOT_IMPLEMENTED);
default: default:
throw new Components.Exception("Invalid type " + desc.type + throw new this._win.DOMError("",
" provided to setLocalDescription"); "Invalid type " + desc.type + " provided to setLocalDescription");
} }
this._queueOrRun({ this._queueOrRun({
@ -660,11 +660,10 @@ RTCPeerConnection.prototype = {
type = Ci.IPeerConnection.kActionAnswer; type = Ci.IPeerConnection.kActionAnswer;
break; break;
case "pranswer": case "pranswer":
throw new Components.Exception("pranswer not yet implemented", throw new this._win.DOMError("", "pranswer not yet implemented");
Cr.NS_ERROR_NOT_IMPLEMENTED);
default: default:
throw new Components.Exception("Invalid type " + desc.type + throw new this._win.DOMError("",
" provided to setRemoteDescription"); "Invalid type " + desc.type + " provided to setRemoteDescription");
} }
this._queueOrRun({ this._queueOrRun({
@ -676,13 +675,13 @@ RTCPeerConnection.prototype = {
}, },
updateIce: function(config, constraints) { updateIce: function(config, constraints) {
throw new Components.Exception("updateIce not yet implemented", throw new this._win.DOMError("", "updateIce not yet implemented");
Cr.NS_ERROR_NOT_IMPLEMENTED);
}, },
addIceCandidate: function(cand, onSuccess, onError) { addIceCandidate: function(cand, onSuccess, onError) {
if (!cand.candidate && !cand.sdpMLineIndex) { if (!cand.candidate && !cand.sdpMLineIndex) {
throw new Components.Exception("Invalid candidate passed to addIceCandidate!"); throw new this._win.DOMError("",
"Invalid candidate passed to addIceCandidate!");
} }
this._onAddIceCandidateSuccess = onSuccess || null; this._onAddIceCandidateSuccess = onSuccess || null;
this._onAddIceCandidateError = onError || null; this._onAddIceCandidateError = onError || null;
@ -697,7 +696,7 @@ RTCPeerConnection.prototype = {
addStream: function(stream, constraints) { addStream: function(stream, constraints) {
if (stream.currentTime === undefined) { if (stream.currentTime === undefined) {
throw new Components.Exception("Invalid stream passed to addStream!"); throw new this._win.DOMError("", "Invalid stream passed to addStream!");
} }
// TODO: Implement constraints. // TODO: Implement constraints.
this._queueOrRun({ this._queueOrRun({
@ -709,13 +708,11 @@ RTCPeerConnection.prototype = {
removeStream: function(stream) { removeStream: function(stream) {
//Bug 844295: Not implementing this functionality. //Bug 844295: Not implementing this functionality.
throw new Components.Exception("removeStream not yet implemented", throw new this._win.DOMError("", "removeStream not yet implemented");
Cr.NS_ERROR_NOT_IMPLEMENTED);
}, },
getStreamById: function(id) { getStreamById: function(id) {
throw new Components.Exception("getStreamById not yet implemented", throw new this._win.DOMError("", "getStreamById not yet implemented");
Cr.NS_ERROR_NOT_IMPLEMENTED);
}, },
close: function() { close: function() {
@ -853,7 +850,8 @@ RTCPeerConnection.prototype = {
if (dict.maxRetransmitTime != undefined && if (dict.maxRetransmitTime != undefined &&
dict.maxRetransmits != undefined) { dict.maxRetransmits != undefined) {
throw new Components.Exception("Both maxRetransmitTime and maxRetransmits cannot be provided"); throw new this._win.DOMError("",
"Both maxRetransmitTime and maxRetransmits cannot be provided");
} }
let protocol; let protocol;
if (dict.protocol == undefined) { if (dict.protocol == undefined) {

View File

@ -31,15 +31,16 @@
} }
} }
// This is a test of the iceServers parsing code. // This is a test of the iceServers parsing code + readable errors
runTest(function () { runTest(function () {
var pc; var pc, pcs;
var exception = null; var exception = null;
var config; var config;
try { pcs = new mozRTCPeerConnection(); } catch (e) { exception = e; } try { pcs = new mozRTCPeerConnection(); } catch (e) { exception = e; }
ok(!exception, "mozRTCPeerConnection() succeeds"); ok(!exception, "mozRTCPeerConnection() succeeds");
pcs = null;
exception = null; exception = null;
makePC(1, false); makePC(1, false);
@ -50,8 +51,6 @@
makePC({ iceServers: [{ url:"" }] }, false); makePC({ iceServers: [{ url:"" }] }, false);
makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false);
makePC({ iceServers: [ makePC({ iceServers: [
{ url:"stun:127.0.0.1" }, { url:"stun:127.0.0.1" },
{ url:"stuns:localhost", foo:"" }, { url:"stuns:localhost", foo:"" },
@ -63,7 +62,15 @@
makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, false); makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, false);
makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false);
try {
pcs = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] });
} catch (e) {
ok(e.message.indexOf("http") > 0,
"mozRTCPeerConnection() constructor has readable exceptions");
}
pcs = null; pcs = null;
SimpleTest.finish(); SimpleTest.finish();
}); });
</script> </script>

View File

@ -36,7 +36,12 @@
try { pconnect.createOffer(step1, failed, { mandatory: [] }); } catch (e) { exception = e; } try { pconnect.createOffer(step1, failed, { mandatory: [] }); } catch (e) { exception = e; }
ok(exception, "createOffer(step1, failed, { mandatory: [] }) throws"); ok(exception, "createOffer(step1, failed, { mandatory: [] }) throws");
exception = null; exception = null;
try { pconnect.createOffer(step1, failed, { mandatory: { FooBar: true } }); } catch (e) { exception = e; } try {
pconnect.createOffer(step1, failed, { mandatory: { FooBar: true } });
} catch (e) {
ok(e.message.indexOf("FooBar") > 0, "createOffer has readable exceptions");
exception = e;
}
ok(exception, "createOffer(step1, failed, { mandatory: { FooBar: true } }) throws"); ok(exception, "createOffer(step1, failed, { mandatory: { FooBar: true } }) throws");
exception = null; exception = null;
try { pconnect.createOffer(step1, failed, { optional: {} }); } catch (e) { exception = e; } try { pconnect.createOffer(step1, failed, { optional: {} }); } catch (e) { exception = e; }