-
Notifications
You must be signed in to change notification settings - Fork 146
InvokeAsync on a stored procedure does not catch exceptions for procs without return data #667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think the problem is around here: SQLProvider/src/SQLProvider/SqlDesignTime.fs Line 408 in 6a089a0
Instead of |
Do you get this compile, do you want to send a PR? |
I'm afraid I'm having some trouble getting a working build environment set up on my machine - I can't compile the code as-is before I make any changes. |
This should be now fixed in the most recent version of SQLProvider (Nuget package). |
After this fix, it appears that I am getting a compile error for every InvokeAsync in my project. I'm building with Visual Studio, but compiling to netstandard2.0, while having also tried netcoreapp3.1. I'm not able to try out net472 on this project, as there are other netcoreapp3.1 depending on this project. The compile error is If I use |
I thought I was going crazy when the same thing happened to me. Thanks for pointing it out. I can also confirm this behavior using a library project targeting .NET Standard 2.1. Version 1.1.76 (from NuGet) works without error, and versions 1.1.78 and 1.1.79 both cause the error message detailed above. |
Sounds strange, I'm using dotnet.exe 3.1.101 targetting netcoreapp2.0 and calling async stored procedure works fine. Now, one thing I did for over 1.1.76 was that I changed the FSharp.Core from 4.2.3 to 4.5.4 |
My project uses FSharp.Core 4.7.0. I wonder if they made changes to the |
Maybe the real reason is actually the Choice-record on the quotation code. Let me try to fix it another way then. Try the 1.1.80, please, just pushed that to the NuGet. |
I assume you know using exceptions as a flow control is a bad practice in .NET:
But I totally agree this as an issue, exceptions shouldn't be swallowed on any conditions. |
I can try this out shortly. However, I wanted to emphasize that I was not using dotnet.exe at all, but, rather, using Visual Studio while targetting netcoreapp3.1, which, I assume, uses F# compiler running on .NET Framework. My previous attempts using dotnet.exe wouldn't work. I think something to do with not finding dependencies or something. |
From a philosophical point of view, I take the stance that "exceptions should be for exceptional cases." If I can anticipate something going wrong, I should explicitly address that case before it could happen. That said, the reason this issue came to my attention was that I was writing code to use someone else's stored procedures that would sometimes raise errors. In this scenario, I don't have the ability to change the stored procedure. I can do my best to code around the cases I know will fail, but I need to be able to handle failures as well (log the exception and the faulty data, stop executing that branch, etc.). Somewhere along the pipeline, those SQL errors get translated to SQLExceptions. (I think that's in SqlClient itself, so that's no fault of this library.) I'd be much happier if that was translated to some kind of "SqlResult" class instead, but I've got to work with the tools I'm given. :) |
Unfortunately, version 1.1.80 fixes the previous issue and allows the code to compile, but it doesn't seem to fix the original problem. I still don't see the exception when using InvokeAsync.
|
@TheJayMann I haven't been able to compile F# projects using this library using |
Ok, found it. It wasn't Async.Catch related, instead the Async.AwaitIAsyncResult in the source code swallowed the exception generated by ExecuteNonQueryAsync. P.S. I can build via both dotnet and VS, but I don't know what I've done differently than others. |
Description
Some stored procedures return result sets of data, but others just return int status codes to indicate success or failure. SQLProvider appears to ignore those status codes, and calling
Invoke
orInvokeAsync
on one of those procedures returnsUnit
orAsync<Unit>
respectively.When one of these procedures throws an error,
Invoke
raises aSqlException
with the text of the error thrown from the procedure. This can be caught using a normaltry...with
block. However, theInvokeAsync
method does not appear to catch this error, and the code continues as if the procedure was successful.Also mentioned in the last comment in #535.
Repro steps
Use this SQL to create a table, procedure, and some example rows:
Now, run this F# code:
These are the results of running the above code in F# interactive:
Finally, for comparison, modify and run the SQL by uncommenting the last SELECT line and commenting the RETURN line at the end. Repeat the F# code and compare the results.
Expected behavior
InvokeAsync
should returnChoice2Of2
with an exception in both test cases.Actual behavior
In the first case,
InvokeAsync
appears to succeed, whileInvoke
returns a clear failure message. In the second test case, bothInvoke
andInvokeAsync
failed as expected.Known workarounds
I can think of two workarounds:
Neither of these are great options.
Related information
The text was updated successfully, but these errors were encountered: