Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method not bound handling #40

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions example/child.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
a.parseComplete();
});

setTimeout(function(){
chan.bind("delayedReverse", function(trans, s) {
if (typeof s !== 'string') {
throw [ "invalid_arguments", 'argument to reverse function should be a string' ];
}
return s.split("").reverse().join("");
});
}, 500)

</script>
</head>
</html>
25 changes: 24 additions & 1 deletion example/parent.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@ <h2> JSChannel example </h2>
Next, here&apos;s notification output:
<div class="output" id="output3"></div>

Finally, here&apos;s callback invocation output:
Now, here&apos;s callback invocation output:
<div class="output" id="output4"></div>

Next, here&apos;s error handling in case of method not bound yet:
<div class="output" id="output5"></div>

Finally, let&apos;s try to call the same method after it has been bound:
<div class="output" id="output6"></div>

<iframe style="display: none;" id="childId" src="child.html"></iframe>
</body>
<script>
Expand Down Expand Up @@ -121,6 +127,23 @@ <h2> JSChannel example </h2>
success: function(v) { docLog(4, "charify all done!" ); }
});

// let's try to invoke a method that has yet not been bound to channel
docLog(5, "invoking reverse method with args 'hello world!' to method 'delayedReverse' which is not yet bound to channel");
function callDelayedReverse(id) {
chan.call({
method: "delayedReverse",
params: "hello world!",
error: function(error, message) { docLog(id, "ERROR: " + error + " (" + message + ")"); },
success: function(v) {
docLog(id, "function returns: '" + v + "'" );
}
});
}
callDelayedReverse(5);

// let's try to invoke the same method after it has been bound (wait 1sec)
docLog(6, "invoking reverse method with args 'hello world!' to method 'delayedReverse' which is now bound to channel (wait 1sec)");
setTimeout(function(){callDelayedReverse(6)}, 1000);

</script>
</html>
119 changes: 61 additions & 58 deletions src/jschannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,71 +359,74 @@

// now, what type of message is this?
if (m.id && method) {
// a request! do we have a registered handler for this request?
if (regTbl[method]) {
var trans = createTransaction(m.id, origin, m.callbacks ? m.callbacks : [ ]);
inTbl[m.id] = { };
try {
// callback handling. we'll magically create functions inside the parameter list for each
// callback
if (m.callbacks && s_isArray(m.callbacks) && m.callbacks.length > 0) {
for (var i = 0; i < m.callbacks.length; i++) {
var path = m.callbacks[i];
var obj = m.params;
var pathItems = path.split('/');
for (var j = 0; j < pathItems.length - 1; j++) {
var cp = pathItems[j];
if (typeof obj[cp] !== 'object') obj[cp] = { };
obj = obj[cp];
}
obj[pathItems[pathItems.length - 1]] = (function() {
var cbName = path;
return function(params) {
return trans.invoke(cbName, params);
};
})();
// a request!
var trans = createTransaction(m.id, origin, m.callbacks ? m.callbacks : [ ]);
inTbl[m.id] = { };
try {
// do we have a registered handler for this request?
if (!regTbl[method]) {
// Oh no! We don't have a registered handler. Maybe it is not yet bound, so better notify of the error.
throw {"error":"method_not_bound_error", "message":"the requested method is not bound on the channel"}
}
// callback handling. we'll magically create functions inside the parameter list for each
// callback
if (m.callbacks && s_isArray(m.callbacks) && m.callbacks.length > 0) {
for (var i = 0; i < m.callbacks.length; i++) {
var path = m.callbacks[i];
var obj = m.params;
var pathItems = path.split('/');
for (var j = 0; j < pathItems.length - 1; j++) {
var cp = pathItems[j];
if (typeof obj[cp] !== 'object') obj[cp] = { };
obj = obj[cp];
}
obj[pathItems[pathItems.length - 1]] = (function() {
var cbName = path;
return function(params) {
return trans.invoke(cbName, params);
};
})();
}
var resp = regTbl[method](trans, m.params);
if (!trans.delayReturn() && !trans.completed()) trans.complete(resp);
} catch(e) {
// automagic handling of exceptions:
var error = "runtime_error";
var message = null;
// * if it's a string then it gets an error code of 'runtime_error' and string is the message
if (typeof e === 'string') {
message = e;
} else if (typeof e === 'object') {
// either an array or an object
// * if it's an array of length two, then array[0] is the code, array[1] is the error message
if (e && s_isArray(e) && e.length == 2) {
error = e[0];
message = e[1];
}
// * if it's an object then we'll look form error and message parameters
else if (typeof e.error === 'string') {
error = e.error;
if (!e.message) message = "";
else if (typeof e.message === 'string') message = e.message;
else e = e.message; // let the stringify/toString message give us a reasonable verbose error string
}
}
var resp = regTbl[method](trans, m.params);
if (!trans.delayReturn() && !trans.completed()) trans.complete(resp);
} catch(e) {
// automagic handling of exceptions:
var error = "runtime_error";
var message = null;
// * if it's a string then it gets an error code of 'runtime_error' and string is the message
if (typeof e === 'string') {
message = e;
} else if (typeof e === 'object') {
// either an array or an object
// * if it's an array of length two, then array[0] is the code, array[1] is the error message
if (e && s_isArray(e) && e.length == 2) {
error = e[0];
message = e[1];
}
// * if it's an object then we'll look form error and message parameters
else if (typeof e.error === 'string') {
error = e.error;
if (!e.message) message = "";
else if (typeof e.message === 'string') message = e.message;
else e = e.message; // let the stringify/toString message give us a reasonable verbose error string
}
}

// message is *still* null, let's try harder
if (message === null) {
try {
message = JSON.stringify(e);
/* On MSIE8, this can result in 'out of memory', which
* leaves message undefined. */
if (typeof(message) == 'undefined')
message = e.toString();
} catch (e2) {
// message is *still* null, let's try harder
if (message === null) {
try {
message = JSON.stringify(e);
/* On MSIE8, this can result in 'out of memory', which
* leaves message undefined. */
if (typeof(message) == 'undefined')
message = e.toString();
}
} catch (e2) {
message = e.toString();
}

trans.error(error,message);
}

trans.error(error,message);
}
} else if (m.id && m.callback) {
if (!outTbl[m.id] ||!outTbl[m.id].callbacks || !outTbl[m.id].callbacks[m.callback])
Expand Down