{"action":"created","issue":{"url":"https://api.github.com/repos/colinbdclark/osc.js/issues/72","repository_url":"https://api.github.com/repos/colinbdclark/osc.js","labels_url":"https://api.github.com/repos/colinbdclark/osc.js/issues/72/labels{/name}","comments_url":"https://api.github.com/repos/colinbdclark/osc.js/issues/72/comments","events_url":"https://api.github.com/repos/colinbdclark/osc.js/issues/72/events","html_url":"https://github.com/colinbdclark/osc.js/issues/72","id":198231732,"number":72,"title":"exceptions from bad OSC?","user":{"login":"d0kt0r0","id":2075184,"avatar_url":"https://avatars.githubusercontent.com/u/2075184?v=3","gravatar_id":"","url":"https://api.github.com/users/d0kt0r0","html_url":"https://github.com/d0kt0r0","followers_url":"https://api.github.com/users/d0kt0r0/followers","following_url":"https://api.github.com/users/d0kt0r0/following{/other_user}","gists_url":"https://api.github.com/users/d0kt0r0/gists{/gist_id}","starred_url":"https://api.github.com/users/d0kt0r0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/d0kt0r0/subscriptions","organizations_url":"https://api.github.com/users/d0kt0r0/orgs","repos_url":"https://api.github.com/users/d0kt0r0/repos","events_url":"https://api.github.com/users/d0kt0r0/events{/privacy}","received_events_url":"https://api.github.com/users/d0kt0r0/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-12-31T13:07:07Z","updated_at":"2016-12-31T22:19:47Z","closed_at":null,"body":"If - using SuperCollider which lets me make this mistake - I send osc.js (running on node 5.5.0 but I'm not sure the version makes any difference) an OSC packet with no address or an ill-formatted address (for example, no opening slash at the beginning) osc.js throws an exception. I'm posting this issue to trigger some discussion about whether such an exception makes sense.\r\n\r\nThere is the old network maxim \"be conservative in what you send and liberal in what you receive\" - in this example, SuperCollider is being used to violate the former, and it would seem osc.js is encouraging a violation of the latter. Of course, one can catch the exception in one's usage of osc.js, but at least to this developer that feels \"insecure\" - either I'm catching and ignoring all exceptions, which isn't so good, or I'm watching for that specific one, in which case I'm still worrying about the specific exceptions I'm not watching for yet.\r\n\r\nI'm not at all sure that I'm \"right\" about this - just triggering some discussion!\r\n"},"comment":{"url":"https://api.github.com/repos/colinbdclark/osc.js/issues/comments/269883882","html_url":"https://github.com/colinbdclark/osc.js/issues/72#issuecomment-269883882","issue_url":"https://api.github.com/repos/colinbdclark/osc.js/issues/72","id":269883882,"user":{"login":"colinbdclark","id":558076,"avatar_url":"https://avatars.githubusercontent.com/u/558076?v=3","gravatar_id":"","url":"https://api.github.com/users/colinbdclark","html_url":"https://github.com/colinbdclark","followers_url":"https://api.github.com/users/colinbdclark/followers","following_url":"https://api.github.com/users/colinbdclark/following{/other_user}","gists_url":"https://api.github.com/users/colinbdclark/gists{/gist_id}","starred_url":"https://api.github.com/users/colinbdclark/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/colinbdclark/subscriptions","organizations_url":"https://api.github.com/users/colinbdclark/orgs","repos_url":"https://api.github.com/users/colinbdclark/repos","events_url":"https://api.github.com/users/colinbdclark/events{/privacy}","received_events_url":"https://api.github.com/users/colinbdclark/received_events","type":"User","site_admin":false},"created_at":"2016-12-31T22:19:47Z","updated_at":"2016-12-31T22:19:47Z","body":"Hi @d0kt0r0,\r\n\r\nThis is a pretty interesting issue, and I'm glad you raised it. I've been mulling it over for most of the day, and have written my initial thoughts about it below. This is not intended as a definitive position—I'm curious about your thoughts and those of others who may be interested, and I'm quite happy to flexible in order to make osc.js a more robust and easier to use library.\r\n\r\nOSC is a funny protocol. It supports several types of packets—messages and bundles—each with their own semantics. Yet it is also very compact and terse. Because messages and bundles mean different things and need to be interpreted differently, an OSC parser needs to be able to unambiguously distinguish between the two.\r\n\r\nIn OSC, the only way to determine the type of an incoming packet is to read its first byte and treat it as a \"type\" field. If the first byte is a <code>/</code>, it's a message. If, on the other hand, it starts with a <code>#</code>, it's probably a bundle. In the absence of one of these two things, it's completely ambiguous which type of message a packet might end up being. \r\n\r\nOSC messages and bundles are not isomorphic, and they mean different things. As a result, an OSC parser has to have two different modes for interpreting incoming packets—one for bundles and another for messages sent at top level. The assumptions used to interpret all the subsequent bytes must change depending on whether we're processing a message or a bundle.\r\n\r\nIt seems to me that the crucial aspect of Postel's Law that may be missing from its articulation in the TCP specification, but is mentioned in the [Wikipedia article on the subject](https://en.wikipedia.org/wiki/Robustness_principle), is the qualifier that a system should accept non-conformant input _\"as long as the meaning is clear\"_. In absence of a clear indication of the type of the ensuing packet, I fear that its meaning is anything but clear.\r\n\r\nAs a side note, there is one mistake I've made and (I think) learned from in osc.js: defaulting to modes in which the system makes inferences about the meaning of a packet when there is insufficient information available. In particular, by default, osc.js will [attempt to infer your argument types when sending messages that omit them](https://github.com/colinbdclark/osc.js/issues/48). In practice, this is very helpful for 80% of use cases, but causes major confusion and bugs in the remaining 20%. A future release will ship with this inference turned off by default so that OSC messages are always unambiguously interpreted. The end result, I hope, is that users will be less confused, will not see their code fail in subtle, unexpected and occasional ways, and if I'm lucky, I'll get fewer bug reports. :)\r\n\r\nI could, in theory, come up with a new inference algorithm for malformed OSC packets. If it doesn't start with a <code>/</code>, and it doesn't start with <code>#bundle</code>, it's _probably_ a malformed message, and some exploratory attempt could be made to parse it as such, or as a bundle if not, etc...\r\n\r\nHowever, in practice, my assumption is that this will make the system more complex, harder to debug, and quite possibly slower. Worst yet, subtle bugs will remain in programs if systems—either senders or receivers—don't make such errors explicit.\r\n\r\nInterestingly, I played around very briefly with SuperCollider's implementation, and it does seem to be quite liberal in what it allows to be sent and also in how it attempts to parse an incoming packet. Here are a few examples:\r\n\r\n    m.sendMsg(\"cat\", \"Meow\");\r\n    Message received on port 57120 from  127.0.0.1 : 57120 : [ cat, Meow ]\r\n\r\nThe above pretty much seems like what you want, right?\r\n\r\n    m.sendMsg(\"#bundle\", \"Meow\");\r\n    Message received on port 57120 from  127.0.0.1 : 57120 : [ ����p��\u0003\u0001 ]\r\n\r\nIt's this latter one that is most interesting, in that a completely invalid message type is parsed successfully in a way that is, by all accounts, erroneous and unpredictable. Presumably, I've been able to provoke the \"bundle\" mode of SuperCollider's OSC parser. Admittedly, it's not a very realistic example of a common mistake, but it does reflect that case where \"sooner or later a packet will come in with that particular combination of errors and attributes [where]... unless the software is prepared, chaos can ensue.\" It looks to me like SuperCollider's implementation is just doing whatever it can and makes no attempt to address robustness issues or a \"suitable protective design.\" But I may well be profoundly confused here, as in many other cases. :)\r\n\r\nThe more I read the full [RFC 1122 articulation of Postel's Law](https://tools.ietf.org/html/rfc1122#page-12), the more I understand it to be specifically pointing out the problems with these ambiguities: \r\n\r\n\"_The second part of the principle is almost as important: software on other hosts may contain deficiencies that make it unwise to exploit legal but obscure protocol features.  It is unwise to stray far from the obvious and simple, lest untoward effects result elsewhere._\"\r\n\r\nInterestingly, some kind of inference or a \"fix-up\" stage for malformed messages and bundles is much easier to do on the sender's end. SuperCollider, for example, has one API for sending messages and a different one for sending bundles. It knows the difference. Similarly, osc.js can detect when a message specification object is lacking a leading <code>/</code> or an address altogether, and could fix it up into some form that might match what you intended. But will it really, all the time, or will it lead to subtle, hard-to-track-down bugs? Do you really want, in the case where you erroneously forgot to specify an <code>address</code> property, for osc.js to quietly send the message with, say, a default of address of <code>\"/\"</code>? The answers to these questions seem very context-dependent.\r\n\r\nThe more I think about your points, though, the more I realize that there are two different issues at play here. First, the issue I've addressed above, which is whether or not an OSC packet can viably be interpreted if its type field is missing. The second, perhaps more germane issue to osc.js, is the question of its robustness in the face of errors. This is something that it started out poorly at, and that I have been trying to improve over the past year or two.\r\n\r\nJust as background information, osc.js is factored into two layers:\r\n\r\n1. the low-level, stateless, function API for creating and reading OSC packets, and\r\n2. the object-oriented transport layer, which provides easy to use, event-based abstractions for sending and receiving OSC messages over specific transport protocols on different platforms\r\n\r\nMy goal with the low-level API is to ensure that it is as simple and explicit as possible. At this level, all errors are raised using JavaScript's Error semantics. If osc.js can't proceed due to a malformed packet, it will throw an Error. Clients of the low-level API are expected to wrap calls to the <code>osc.read*</code> and <code>osc.write*</code> functions in suitable <code>try</code>/<code>catch</code> blocks, handling the Error as appropriate or allowing it to propagate upwards. Not very convenient, but simple and explicit.\r\n\r\nOn the other hand, the higher-level Transport layer is event-based, and the base <code>Port</code> prototype provides an <code>error</code> event which will fire in case of errors when sending or receiving packets. This semantic may need to be broadened somewhat to provide events for certain classes of errors, I'm not sure. In any case where an error is raised, a Port should, if it is bug-free, fire its <code>error</code> event and move along. If the error resulted from reception of a malformed message, it is simply discarded. If it was malformed on send, it is similarly discarded and not sent. A softer, arguably more robust way of handling error cases. Again, advice from RFC1122: \"_An undefined code might be logged... but it must not cause a failure._\"\r\n\r\nSo, if you're encountering explicit exceptions being throw when a malformed OSC message is received or sent using osc.js <code>Port</code> objects, this is just flat out a bug. Interestingly, when I modified the [osc.js-examples send-to-supercollider](https://github.com/colinbdclark/osc.js-examples/blob/master/send-to-supercollider/index.js#L19) to send a message with an address of <code>\"cat\"</code>, it did indeed throw an Error that wasn't caught, causing the Node.js process to halt. That's a bug, and there may be other similar cases. I've filed #73 about this, and will fix it as soon as I get a chance (or will happily take pull requests).\r\n\r\nAnyway, this turned out much longer than I had anticipated—again, it's because it was such an interesting question you raised. I don't know if I'm fully thinking clearly about this issue, so I'd very much like to hear your thoughts and feedback.\r\n\r\nHappy New Year, @d0kt0r0, and thanks again!"}}
{"actor":{"display_login":"colinbdclark"}}