supabase-community / postgrest-csharp

A C# Client library for Postgrest
https://supabase-community.github.io/postgrest-csharp/api/Postgrest.html
MIT License
114 stars 22 forks source link

Calling Count() query raises ProtocolViolationException #45

Closed CoryParsnipson closed 1 year ago

CoryParsnipson commented 1 year ago

Hi,

I want to get a count of all the rows in my table with this query:

return await Supabase.Client.Instance.From<MyModel>()
     .Select("id")
     .Count(Postgrest.Constants.CountType.Exact);

And I get a ProtocolViolationException. The top of the stack trace looks like this:

ProtocolViolationException: Cannot send a content-body with this verb-type.
System.Net.HttpWebRequest.MyGetRequestStreamAsync (System.Threading.CancellationToken cancellationToken) (at <f326fc0a10e542b298005d1c9ab100aa>:0)
System.Net.HttpWebRequest.RunWithTimeout[T] (System.Func`2[T,TResult] func) (at <f326fc0a10e542b298005d1c9ab100aa>:0)
System.Net.HttpWebRequest.GetRequestStreamAsync () (at <f326fc0a10e542b298005d1c9ab100aa>:0)
System.Net.Http.MonoWebRequestHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) (at <d4a37b33de154aa9a7a1a042eef9b39c>:0)
System.Net.Http.HttpClient.SendAsyncWorker (System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) (at <d4a37b33de154aa9a7a1a042eef9b39c>:0)
Postgrest.Helpers.MakeRequest (System.Net.Http.HttpMethod method, System.String url, Newtonsoft.Json.JsonSerializerSettings serializerSettings, System.Object data, System.Collections.Generic.Dictionary`2[TKey,TValue] headers) (at Library/PackageCache/com.supabase.unity@ada643f912/supabase-cloned/supabase-csharp/modules/postgrest-csharp/Postgrest/Helpers.cs:80)
Postgrest.Table`1+<>c__DisplayClass44_0[T].<Count>b__0 () (at Library/PackageCache/com.supabase.unity@ada643f912/supabase-cloned/supabase-csharp/modules/postgrest-csharp/Postgrest/Table.cs:474)

If I look in Table.cs at the Count() function (line 455 in my version) I see this:

        public Task<int> Count(CountType type)
        {
            var tsc = new TaskCompletionSource<int>();

            Task.Run(async () =>
            {
                method = HttpMethod.Head;

                var attr = type.GetAttribute<MapToAttribute>();

From the error message, it looks like the Head HTTP request method doesn't allow a body to be sent. So if I change HttpMethod.Head to HttpMethod.Get, everything works fine. Something in here is including a message body when it's not supposed to, I guess?

I think you can reproduce this by trying to make a Count() request on any given query. If not, I am using this postgrest-csharp bundled in unity-supabase cloned from the repo three days ago. I'd be happy to provide additional information if necessary.

Thanks!

CoryParsnipson commented 1 year ago

Actually I just looked at the supabase-unity repo and followed the submodules all the way back to postgrest-csharp, and it looks like I'm using this commit from May 24:

https://github.com/supabase-community/postgrest-csharp/commit/c57c4140d812f92c28fdf50a2bbd2282284c095c

acupofjose commented 1 year ago

@CoryParsnipson thanks for such a detailed issue! Unfortunately, I'm not able to duplicate the issue you're having from the latest release on this repo. The associated test case is here: https://github.com/supabase-community/postgrest-csharp/blob/a6eb5afa978175a3e39fba3f4c45081cbac4a586/PostgrestTests/ClientApi.cs#L974-L992

I thought maybe you'd found an edge case where adding Select() to the call would make it error, but that didn't seem to break anything for me?

Are you able to continue just by changing that source file? Or would updating the supabase-cloned folder in the repo to the latest release (note that you need to include submodules in the command git clone --recursive git://github.com/supabase-community/supabase-csharp.git) I don't maintain the supabase-unity repo - it's a bit out of my wheelhouse!

CoryParsnipson commented 1 year ago

I'm going to try updating the packages individually like you suggested and get back to you. Thanks!

Taking out the Select() call makes no difference for me. If I change the source file to use GET, everything works fine for me. I finished implementing the feature I was doing, so I figured I tried to debug what is happening with my thing "for real", since if someone updates the package, it'll break everything mysteriously sometime in the future.

Also, yes, looks like the supabase-unity repo is a couple months out of date. I think it's mainly just bundling all the other packages together, so I thought it would be better to bring up the issue here. If I figure out how to fix it, I'll contact the maintainers to see if I can get an update in.

acupofjose commented 1 year ago

Keep me updated - Thanks for your responsiveness!

CoryParsnipson commented 1 year ago

Ok after some trial and error, I was able to update the postgrest submodule to 2.0.11 (the latest one) and the bug went away.

It's looking like this could be an issue introduced during bundling in the supabase-unity repo. I'll go bother them now...

Thanks!

acupofjose commented 1 year ago

Very nice! Glad to hear you’re making progress!

CoryParsnipson commented 1 year ago

Yeah I'm close, I just need to resolve a couple things in the supabase unity package.

Thanks for trying to reproduce on your end.