views:

172

answers:

1

Short question: What does an exception's "sourceID" refer to, and how can I link it to the relevant source string/file?

Longer story:

I am running Javascript code in an iPhone native app through [UIWebView stringByEvaluatingJavaScriptFromString:]. To help development, and later check user-provided code, I use the following function to safely run any code:

// Inside @implementation MyJS
- (NSString *)runJS:(NSString *)js {
    // Do some escaping on 'js' to make it look like a string literal.
    js = escape(js);
    NSString *result =
        [webView stringByEvaluatingJavaScriptFromString:
            [NSString stringWithFormat:@"try { JSON.stringify(eval(\"%@\")); } except (e) { JSON.stringify(e); }", js]
        ];
    return result;
}

If all goes well, [MyJS runJS:js] runs fine and returns a JSON string containing the result of the evaluation of the last statement in the 'js' code.

Now if bad things happen during the evaluation, I get a JSONified exception object. For example, in case of a syntax error in the 'js' code, I get something like this:

{"message":"Parse error","line":1,"sourceId":26121296}

Which is already quite useful to track problems...

However, as I run multiple strings through runJS:, I would like to be able to pinpoint which one caused the exception (because a runtime error could come from a function that was created in a previous javascript code string). This "sourceId" property looks interesting, but I cannot find what it points to. It looks like a pointer address (similar value as pointers to other objects), but it doesn't match with any of the strings I've passed to the evaluator. How can I make this link?

For bonus points: Is there any documentation available about the UIWebView-specific javascript environment, like this exception object? The Safari Web Content Guide is nice, but doesn't go into this kind of details.

A: 

Worst-case solution:

Inside each js string being evaluated, add some code that throws an exception, catches it, extracts the sourceId and somehow exposes it so that the runJS: method can keep a record of which sourceId goes with which string.

(Hopefully someone will find a better way and help bury this ugly answer!)

squelart