-
Notifications
You must be signed in to change notification settings - Fork 421
Support try/catch/finally Around an Abstract Function Which Might Throw #1264
Comments
This is pretty hard to do, not least because of that little foot note at the end: "We'd also need to handle the object passed to the catch." A possible work around that already works, is to wrap the call to fn inside a concrete model function that checks the preconditions of fn and throws an appropriate exception if they fail. Then we can go back to regarding fn as pure and well behaved. If fn uses exceptions to communicate rare conditions rather than precondition failures, then there is very little we can do statically. This is one of those situations where we throw up our hands and say "please change your code". In this instance you change your code by introducing a non throwing version of fn that returns status codes (or even exceptions) as return results. |
I updated with a version where we also store the thrown value which is either I'm not sure why this is different from E.g. we can treat one of these calls effectively as: var {success, exception, value} = callHelper(fn); We can do that automatically. In subsequent code: if (!success) {
throw exception;
} This already works because conditional throws in conditional branches are already implemented. |
A more direct way to fit in with current exception handling logic might be to provide a model function that defines an abstract function that returns not an AbstractValue, but a PossiblyNormalCompletion. The conditions we need for the PNC could well come from model variables that are set in a try catch that wraps the call. |
I can actually model this helper in user space already. :) (function () {
function call(fn) {
var template = {};
__makePartial(template);
__makeSimple(template);
var res = __residual(template, function(fn) {
var value;
var exception;
var success = true;
try {
value = fn();
} catch (e) {
exception = e;
success = false;
}
return {value, exception, success};
}, fn);
if (!res.success) {
throw res.exception;
}
return res.value;
}
var fn = __abstract('function', 'fn');
var x = 1;
try {
call(fn);
x = 2;
call(fn);
x = 3;
} catch (err) {
}
result = x;
})(); It generates some pretty interesting code though. EDIT: Even more interesting is that the serializer yields incorrect code. |
…a try This is a follow up to facebookarchive#1142. If we call an unknown function it might throw which will take a different control Flow. facebookarchive#1264 is the follow up to do this properly but since we don't have a use case right now, we can just issue a recoverable error if this happens.
…a try This is a follow up to facebookarchive#1142. If we call an unknown function it might throw which will take a different control Flow. facebookarchive#1264 is the follow up to do this properly but since we don't have a use case right now, we can just issue a recoverable error if this happens.
…a try This is a follow up to facebookarchive#1142. If we call an unknown function it might throw which will take a different control Flow. facebookarchive#1264 is the follow up to do this properly but since we don't have a use case right now, we can just issue a recoverable error if this happens.
Summary: This is a follow up to #1142. If we call an unknown function it might throw which will take a different control flow. #1264 is the follow up to do this properly but since we don't have a use case right now, we can just issue a recoverable error if this happens. Closes #1284 Differential Revision: D6669732 Pulled By: sebmarkbage fbshipit-source-id: 32ff40d4afba589ce60193b01034dfb8bc764378
As outlined in facebookarchive#1264 we know that it is safe to throw in an pure function since then the return value will be ignored and therefore its state doesn't matter. The only time it matters, is if there is a try/catch around it which we already warn about. This means that we don't have to error when calling a non-function. I also plan to add more of these cases like this. So I took the liberty to also move this category of tests into a separate folder.
As outlined in facebookarchive#1264 we know that it is safe to throw in an pure function since then the return value will be ignored and therefore its state doesn't matter. The only time it matters, is if there is a try/catch around it which we already warn about. This means that we don't have to error when calling a non-function. I also plan to add more of these cases like this. So I took the liberty to also move this category of tests into a separate folder.
As outlined in facebookarchive#1264 we know that it is safe to throw in an pure function since then the return value will be ignored and therefore its state doesn't matter. The only time it matters, is if there is a try/catch around it which we already warn about. This means that we don't have to error when calling a non-function. I also plan to add more of these cases like this. So I took the liberty to also move this category of tests into a separate folder.
Summary: As outlined in #1264 we know that it is safe to throw in an pure function since then the return value will be ignored and therefore its state doesn't matter. The only time it matters, is if there is a try/catch/finally around it which we already warn about. This means that we don't have to error when calling a non-function. I also plan to add more of these cases like this. So I took the liberty to also move this category of tests into a separate folder. Closes #1321 Differential Revision: D6706415 Pulled By: sebmarkbage fbshipit-source-id: 175ee17a3b02cb8799ee73a4661d194b15ebc40f
I'm going to need to add a lot of these things that might throw so I wanted to start preparing the infrastructure for fixing facebookarchive#1264. The idea is that code inside this scope might emit temporal operations that might throw. In the future we can wrap these in a try/catch to extract a caught error and a flag. These can be used to generate a PossiblyNormalCompletion. However, for now I just keep the existing strategy of erroring in this case while I add more callers of this helper.
I'm going to need to add a lot of these things that might throw so I wanted to start preparing the infrastructure for fixing facebookarchive#1264. The idea is that code inside this scope might emit temporal operations that might throw. In the future we can wrap these in a try/catch to extract a caught error and a flag. These can be used to generate a PossiblyNormalCompletion. However, for now I just keep the existing strategy of erroring in this case while I add more callers of this helper.
I'm going to need to add a lot of these things that might throw so I wanted to start preparing the infrastructure for fixing facebookarchive#1264. The idea is that code inside this scope might emit temporal operations that might throw. In the future we can wrap these in a try/catch to extract a caught error and a flag. These can be used to generate a PossiblyNormalCompletion. However, for now I just keep the existing strategy of erroring in this case while I add more callers of this helper.
I'm going to need to add a lot of these things that might throw so I wanted to start preparing the infrastructure for fixing facebookarchive#1264. The idea is that code inside this scope might emit temporal operations that might throw. In the future we can wrap these in a try/catch to extract a caught error and a flag. These can be used to generate a PossiblyNormalCompletion. However, for now I just keep the existing strategy of erroring in this case while I add more callers of this helper.
I'm going to need to add a lot of these things that might throw so I wanted to start preparing the infrastructure for fixing facebookarchive#1264. The idea is that code inside this scope might emit temporal operations that might throw. In the future we can wrap these in a try/catch to extract a caught error and a flag. These can be used to generate a PossiblyNormalCompletion. However, for now I just keep the existing strategy of erroring in this case while I add more callers of this helper.
Summary: I'm going to need to add a lot of these things that might throw so I wanted to start preparing the infrastructure for #1264. See that issue for more info on the approach. The idea is that code inside this scope might emit temporal operations that might throw. In the future we can wrap these in a try/catch to extract a caught error and a flag. These can be used to generate a PossiblyNormalCompletion. However, for now I just keep the existing strategy of erroring in this case while I add more callers of this helper. Closes #1326 Differential Revision: D6735259 Pulled By: sebmarkbage fbshipit-source-id: c16a4ed2d4eaf9120dc38d60a4922c7cab0ba59c
Sorry, why is this closed? The original issue is not fixed and we might need it at some point later. |
This is a follow up issue for #1142. In that implementation, we don't support catching an error from an abstract function call. This is not very high priority since I think this will be very rare and we can properly warn for this.
Imagine something like this in a pure context (e.g. in an additional function or React component):
Currently the code will assume that neither call will throw and therefore always result in
result = 3
.To solve this I think we need calling an abstract function to be able to conditionally yield an abrupt completion. Yielding a joined completion.
The
joinCondition
for which branch to take isn't a direct value but whether the invocation worked or not.I imagine we can have the call generator derive a value, a success flag and a thrown value. So the serialized code would be something like:
The success flag value can be what the
joinCondition
uses. That way thejoinCondition
propagates properly when other values get joined. Subsequent emitted statements would get conditional on this value.So the generated code end up something like this:
The text was updated successfully, but these errors were encountered: