Skip to content
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

SqlException fails to deserialize via BinaryFormatter #778

Closed
danlyons-softek opened this issue Oct 29, 2020 · 2 comments · Fixed by #780
Closed

SqlException fails to deserialize via BinaryFormatter #778

danlyons-softek opened this issue Oct 29, 2020 · 2 comments · Fixed by #780
Labels
🐛 Bug! Something isn't right !

Comments

@danlyons-softek
Copy link

Describe the bug

In one project I work on, RPC is done via RabbitMQ, serializing request/reply data with BinaryFormatter. Recently, I ran across an error when deserializing SqlExceptions raised on the back-end.

There appear to be two distinct exceptions raised:

TargetInvokcationException with an inner exception of InvalidCastException when the deserialized exception includes SqlException as its inner exception:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.InvalidCastException: Object must implement IConvertible.
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at System.Runtime.Serialization.FormatterConverter.Convert(Object value, Type type)
   at System.Runtime.Serialization.SerializationInfo.GetValue(String name, Type type)
   at System.Exception..ctor(SerializationInfo info, StreamingContext context)
   at Panther.Common.Database.DBException..ctor(SerializationInfo info, StreamingContext context) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.common.database\DBException.cs:line 136

   --- End of inner exception stack trace ---
   at Panther.Proxy.Common.SyncRequestHelper.SendRequestAsync[T](Object scope, Object payload, TimeSpan timeout, String queueName) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.common\SyncRequestHelper.cs:line 209
   at Panther.Proxy.Common.SyncRequestHelper.SendRequestAsync[T](String queueName, Object scope, Object payload, TimeSpan timeout) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.common\SyncRequestHelper.cs:line 116
   at Panther.Common.Extensions.TaskExtensions.SynchronizeResult[T](Task`1 task) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.common\Extensions\TaskExtensions.cs:line 28
   at Panther.Proxy.Common.SyncRequestHelper.SendRequest[T](String queueName, Object scope, Object payload, TimeSpan timeout) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.common\SyncRequestHelper.cs:line 75
   at Panther.Proxy.Client.BaseFailoverProxy.SendRequest[T](Keys scope, Object payload) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.client\BaseFailoverProxy.cs:line 28
   at Panther.Proxy.Client.PrivCache.PrivCacheFailoverProxy.SavePrivilegeValues(IEnumerable`1 accountPrivs, String savedBy) in C:\BuildAgent\work\fb44abcc89900f2b\src\server\panther.proxy.client\PrivCache\PrivCacheFailoverProxy.cs:line 352
   at Panther.Api.Controllers.PrivilegeController.SavePrivileges(IEnumerable`1 privileges) in C:\BuildAgent\work\fb44abcc89900f2b\src\web\panther.api.core\Controllers\PrivilegeController.cs:line 270
   at lambda_method(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

SerializationException when the deserialized exception is SqlException itself:

System.Runtime.Serialization.SerializationException: Unable to load type Microsoft.Data.SqlClient.SqlException required for deserialization.
   at System.Runtime.Serialization.ObjectManager.DoFixups()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(BinaryParser serParser, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, Boolean check)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   at testdbexception.Program.Main(String[] args) in C:\danl\testdbexception\Program.cs:line 37

To reproduce

Attached is a minimal reproduction of the issue. TestDir has functions to create a test table, insert a value, and drop the test table. Program calls into TestDir with two inserts of the same value to trigger a SqlException for a primary key violation, then serializes and deserializes the exception with BinaryFormatter.

testdbexception.zip

Expected behavior

I would expect the deserialization to complete successfully, particularly given SqlException is marked as serializable, implements ISerializable, and serializes without issue.

Further technical details

Microsoft.Data.SqlClient version: latest (2.0.1)
.NET target: Core 3.1
SQL Server version: SQL Server 2016
Operating system: Windows 10 (dev machine), Server 2016 (production machine)

@danlyons-softek
Copy link
Author

I noticed that BinaryFormatter is deprecated in .NET 5.0 and beyond, but I thought it best to err on the side of reporting the issue.

In my particular case, this is not a huge issue, as the RPC call was returning an exception anyway. It's merely unfortunate that the exception encountered by the caller is a serialization-related exception rather than the exception returned from the RPC call. However, the back-end includes logging as well, so the original exception information is not entirely lost.

@cheenamalhotra
Copy link
Member

Hi @danlyons-softek

Thanks for reporting this issue.
PR #780 fixes this issue, we'll try to get this merged soon for next release!

@cheenamalhotra cheenamalhotra added this to To do in SqlClient v2.1 via automation Oct 30, 2020
@cheenamalhotra cheenamalhotra moved this from To do to In progress in SqlClient v2.1 Oct 30, 2020
cheenamalhotra added a commit to cheenamalhotra/SqlClient that referenced this issue Oct 30, 2020
@cheenamalhotra cheenamalhotra added the 🐛 Bug! Something isn't right ! label Nov 3, 2020
SqlClient v2.1 automation moved this from In progress to Done Nov 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 Bug! Something isn't right !
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

2 participants