Up tonight, a bit of hacking on fab.js proper. Last night I encountered this stack trace:
cstrom@whitefall:~/repos/my_fab_game$ ./game.jsI solved the problem by reworking my (fab) app, but I am thinking that maybe I need to resolve this in fab.js itself. After a bit of legwork, I decide the best point of attack in that stack is
/home/cstrom/repos/my_fab_game/game.js:38
say: obj.body.say.substr(0,100)
^
TypeError: Cannot call method 'substr' of undefined
at listener (/home/cstrom/repos/my_fab_game/game.js:38:35)
at listener (/home/cstrom/.node_libraries/fab/apps/fab.map.js:11:19)
at IncomingMessage.<anonymous> (/home/cstrom/.node_libraries/fab/apps/fab.nodejs.js:29:36)
at IncomingMessage.emit (events:25:26)
at HTTPParser.onBody (http:98:23)
at Stream.ondata (http:745:22)
at IOWatcher.callback (net:373:31)
at node.js:204:9
fab.nodejs.js
:if ( inbound ) {Inside
request
.addListener( "end", inbound )
.addListener( "data", function( body ) {
if ( inbound ) inbound = inbound({ body: body });
})
}
fab.nodejs.js
, I add some debugging code to see what the body
is://...After sending some dummy chat data to my (fab) game, I find this debug output:
if ( inbound ) {
request
.addListener( "end", inbound )
.addListener( "data", function( body ) {
puts("[fab.node.js] data body isa " + typeof(body));
puts("[fab.node.js] data body toString(): " + body.toString());
for (var prop in body) {
puts("[fab.node.js] " + prop + ": " + body[prop]);
}
if ( inbound ) inbound = inbound({ body: body.toString ? body.toString() : body });
})
}
//...
cstrom@whitefall:~/repos/my_fab_game$ ./game.jsAs expected (after last night's investigation), the body is not a string literal, but rather is a
[fab.node.js] data body isa object
[fab.node.js] data body toString(): {"id":"foo", "say":"hi"}
[fab.node.js] 0: 123
[fab.node.js] 1: 34
[fab.node.js] 2: 105
[fab.node.js] 3: 100
...
String
object. The later does not work well with things like JSON.parse
, so I need to come up with a way of ensuring that body
a string literal.I do investigate up the stack a bit, but am frustrated to find that it should already be a string literal. From
http.js
in node.js:parser.incoming.emit('data', b.slice(start, start+len));The slice method ought to produce a string literal:
cstrom@whitefall:~/repos/my_fab_game$ rlwrap node-replBut in practice, sadly, that is not what is emitted by the
Welcome to the Node.js REPL.
Enter ECMAScript at the prompt.
Tip 1: Use 'rlwrap node-repl' for a better interface
Tip 2: Type Control-D to exit.
Type '.help' for options.
node> str = new String("foo")
{ '0': 'f', '1': 'o', '2': 'o' }
node> typeof str
'object'
node> str.slice(1,4)
'oo'
node> typeof str.slice(1,4)
'string'
onBody
callback. Ah, well. I can resolve the issue similarly to last night: by calling toString()
on the body in fab.nodejs.js
:if ( inbound ) {Now I can be sure that any data POSTed to any of my (fab) apps will be string literals and thus JSON.parse friendly. That's a good stopping point for tonight.
request
.addListener( "end", inbound )
.addListener( "data", function( body ) {
if ( inbound ) inbound = inbound({ body: body.toString ? body.toString() : body });
})
}
Day #129
No comments:
Post a Comment