Closed flat-eric147 closed 1 month ago
Hi @flat-eric147,
It's difficult to provide a concise answer without knowing what XMLHttpRequest
is. It isn't a JavaScript built-in, so it could be a .NET type, a COM type, or perhaps something else. Can you say anything about it? How are you exposing it to the script engine?
Thanks!
Hi, apologies, I totally forgot that I added a binding to XMLHttpRequest, so yes then it's a .NET type.
I am exposing it through AddCOMType("XMLHttpRequest", "MSXML2.XMLHTTP");
So I guess that means I have no chance :)
Hi @flat-eric147,
One possibility is to modify the onreadystatechange
property so that the assigned callback is always invoked within a try...catch
statement. Unfortunately, you're using a COM type, so extending it or modifying its implementation is probably not an option. One thing you can still do, however, is wrap it, and JavaScript's Proxy
provides a nice mechanism for that.
First, let's import the COM type without exposing it to the script engine. We can use ExtendedHostFunctions.comType
for that, although it's a bit "off-label":
var xmlHttpRequest = new ExtendedHostFunctions().comType("MSXML2.XMLHTTP");
Next, let's define a function that builds a proxy for that type. The proxy will intercept construction and return a proxy to the constructed instance that adds error handling to the onreadystatechange
callback:
dynamic makeProxy = engine.Evaluate(@"
impl => new Proxy(impl, {
construct(target, args) {
let callback;
return new Proxy(new target(...args), {
get(target, name, receiver) {
if (name === 'onreadystatechange') {
return callback;
}
return Reflect.get(target, name, receiver);
},
set(target, name, value, receiver) {
if (name === 'onreadystatechange') {
callback = value;
value = function () {
try {
callback();
} catch (exception) {
// -=> HANDLE EXCEPTION HERE <=-
}
}
}
return Reflect.set(target, name, value, receiver);
}
});
}
})
");
Finally, we'll call our function to build the proxy and expose it to the script engine as XMLHttpRequest
:
engine.Script.XMLHttpRequest = makeProxy(xmlHttpRequest);
Note that you can do whatever you want inside that catch
clause – log the exception, invoke another host method, etc. Please let us know if this solution works for you.
Thanks!
oh boy, this makes me almost cry, it's a thing of great beauty. It works nicely! I'm glad I asked, I would have never worked that out on my own. Thank you!!!!
Thanks for letting us know! Please reopen this issue if you have additional questions or comments. Thanks again!
Hi,
how would ClearScript catch an exception when an error occurs in an async code segment? Take for example the following code:
` var request = new XMLHttpRequest() request.onreadystatechange = function () { if (request.readyState == 4 && request.status == 200) { try { var json = JSON.parse(request.responseText)
} } request.open("GET", "https://jsonplaceholder.typicode.com/users", true) request.setRequestHeader("Content-Type", "application/json") request.send() `
So if I hadn't placed the try/catch block the error would go undetected. Is there anything I can do in ClearScript to get an error message?