grpc-dart
grpc-dart copied to clipboard
Dart Web gRPC error logging could be improved
I get a gRPC Error (14, XhrConnection connection-error) when I use Dart gRPC in the browser. Dart gRPC on Android performs properly, without an error.
grpc: git: url: https://github.com/grpc/grpc-dart.git # Need this bug fix: https://github.com/grpc/grpc-dart/pull/287 ref: c513e1467f21e498385f4aefa7e370601263034e
The above is master.
Repro steps
I have created a reproducer for the problem. https://github.com/chipkent/dart-grpc-web-bug
Directions for reproducing the problem can be found at: https://github.com/chipkent/dart-grpc-web-bug/blob/master/dart_grpc_web_bug/README.md
Expected result: I expect dart gRPC web to connect and function, without exception, in a manner similar to dart gRPC Android.
Actual result: Android functions properly. Web returns gRPC Error (14, XhrConnection connection-error)
Details
A complete reproducer can be found at: https://github.com/chipkent/dart-grpc-web-bug
I am running Android Studio on MacOS. I have confirmed the same problem when the server is implemented in Go and running on Linux.
Adding some print statements yielded this stack trace:
DBG -- XhrConnection connection-error:
XMLHttpRequest error.
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 268:20 get current
packages/http/src/browser_client.dart 84:22
I'm using Master branch ref: 39c7511 since #287 broke server streaming. Does that help you ?
Unfortunately, ref: 39c751128cff276374e5e23057136f4e0c18018c doesn't help me. I need the #287 feature because my app is android and web. The code doesn't compile with the earlier version. If there is a way to try the earlier feature with conditional imports, I'm happy to try, but when I last looked at conditional imports, it seemed like they were mostly removed from Dart.
@gustav3d Can you also post your GRPCweb.dart?
I turn off https during local testing on port 5002, and i run a live server on 5001.
import 'dart:html' as html; import 'package:grpc/grpc_connection_interface.dart'; import 'package:grpc/grpc_web.dart';
class GRPC{
static ClientChannelBase getChannel(int port) { var host=html.window.location.hostname; return GrpcWebClientChannel.xhr(port==5002? Uri.http(host +':'+port.toString(), ""): Uri.https(host +':'+port.toString(), "")); } }
Rolling back to the older commit yields "gRPC Error (14, XhrConnection status 0)" for the web.
By older commit, I mean ref: 39c7511.
Strange, it works for me. Do you have CORs and grpc-web(as proxy or in process) enabled on the GRPC server ?
access-control-allow-origin: * access-control-expose-headers: Grpc-Status,Grpc-Message
Your comment triggered a few hours of research into this problem. The documentation for grpc-web is quite weak. Am I reading it correctly that I need to be running Envoy or another proxy to map between my browser web-grpc requests and my backend "normal" grpc server, because web-grpc and normal grpc are currently different protocols?
Yes, because in a browser you cant access http2 as a transport layer. So http1 proxy, or in process http1 body wrapper on the server is needed.
There are also options based on websockets, but that requires implementation on the web client too. And for Dart, i dont know of any.
On Monday, 8 June 2020, chipkent [email protected] wrote:
Your comment triggered a few hours of research into this problem. The documentation for grpc-web is quite weak. Am I reading it correctly that I need to be running Envoy or another proxy to map between my browser web-grpc requests and my backend "normal" grpc server, because web-grpc and normal grpc are currently different protocols?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/grpc/grpc-dart/issues/312#issuecomment-640383288, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABCY4M7MYTF5JU4LTM3ML3RVR3MDANCNFSM4NQL2KPQ .
@gustav3d Thank you for your help. I added a grpc-web proxy, and all but one of my rpc calls are working.
I would never have guessed that a translation proxy was needed. I think that this bug report can be closed, but a more helpful error message than "gRPC Error (14, XhrConnection connection-error)" is needed. Something along the lines of "you are attempting to connect to a gRPC port instead of a gRPC-web proxy port" would have saved me many hours.
We are here to help each other :)
What's the problem with that rpc call ?
Good to know is that regarding GRPC streaming on the web client. Currently only server streaming works. And then it sucks, due to xhr can't stream binary. so it's base64 encoded.
ctr shift i in chrome brings up the developer tab , where you in the network tab. can see more details by clicking on the requests. There is also a console drawer.
On Tue, 9 Jun 2020 at 04:59, chipkent [email protected] wrote:
@gustav3d https://github.com/gustav3d Thank you for your help. I added a grpc-web proxy, and all but one of my rpc calls are working.
I would never have guessed that a translation proxy was needed. I think that this bug report can be closed, but a more helpful error message than "gRPC Error (14, XhrConnection connection-error)" is needed. Something along the lines of "you are attempting to connect to a gRPC port instead of a gRPC-web proxy port" would have saved me many hours.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/grpc/grpc-dart/issues/312#issuecomment-640998513, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABCY4KKIYCEGMQCHJHAOQ3RVWQPVANCNFSM4NQL2KPQ .
Thanks for the debugging details. I will dig in tonight.
My one rpc call that is having problems seems to not return. My go server logs that it completed calculations and returned in 10ms. The associated go proxy indicates the same. I plan to try the envoy proxy as well, to confirm that this is not a proxy problem.
I pulled up the problematic rpc call in the chrome developer tools. This call says "CAUTION: request is not finished yet!". It has been like this for 10 min. Under XHR, the status is pending. The server side gRPC execution took < 1 sec. A different grpc call that works, which I think has a larger payload, is taking 407ms.
Any thoughts on identifying what is going on?
I do notice one other thing in the network diagnostics. The bad grpc-web call has two entries. One with a type of XHR and another with an empty type. The empty type case looks like it finished. The other has the request not finished. I do not see these double entries on other calls.
Scratch that. I do see the double calls for the working grpc-web calls.
I have now solved the problem with the bad grpc-web call. It ended up being a deadlock in my server-side rpc function, which was only triggered by the web interface.
In case it is useful to anyone, I did get the Envoy proxy up. When I looked at the statistics, I never saw stats for the bad rpc method, even though my underlying grpc server was called. This seems to indicate that no Envoy stats are recoreded if your server function deadlocks.
Now that this is resolved, my only request is better error logging for the original connection problem. Details on the connection error would be hugely beneficial. An error indicating that I was trying to connect a gRPC-web client to a gRPC server would have saved many hours.
@gustav3d Thanks for the help!
@chipkent @gustav3d even with the proper envoy I'm also getting mixed results, I have two RPCs on the same grpc service and one works and the other doesn't, I do have the cors headers and stuff, any idae what could be causing this or how to debug it further?