-
Notifications
You must be signed in to change notification settings - Fork 54
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
"Not compatible with a supported function shape" when using RequestContext parameter #464
Comments
Just been digging through the source and I can't understand why Wondering if I need to make my own |
Does |
And/or have you tried typing your function |
Hey @kevmoo thanks for the suggestions. Yeah pub sub class should be fine, this is it: pub_sub_types.dartimport 'dart:convert';
import 'dart:typed_data';
import 'package:json_annotation/json_annotation.dart';
part 'pub_sub_types.g.dart';
@JsonSerializable()
class PubSub {
final PubSubMessage message;
final String subscription;
PubSub(this.message, this.subscription);
factory PubSub.fromJson(Map<String, dynamic> json) {
try {
return _$PubSubFromJson(json);
} catch (e, s) {
print('PubSub: Failed to parse json: $json');
rethrow;
}
}
Map<String, dynamic> toJson() => _$PubSubToJson(this);
}
@JsonSerializable()
class PubSubMessage {
final String? data;
final Map<String, String>? attributes;
final String messageId;
final DateTime publishTime;
bool hasData() => data != null;
Map<String, dynamic> jsonDecoded() => json.decode(dataDecoded());
String dataDecoded() => utf8.decode(dataBytes());
Uint8List dataBytes() =>
data != null ? base64Decode(data!) : throw Exception('Data excected');
PubSubMessage(this.data, this.messageId, this.publishTime, this.attributes);
factory PubSubMessage.fromJson(Map<String, dynamic> json) {
try {
return _$PubSubMessageFromJson(json);
} catch (e, s) {
print('PubSubMessage: Failed to parse json: $json');
rethrow;
}
}
Map<String, dynamic> toJson() => _$PubSubMessageToJson(this);
}
// This was a test to see if returning this instead of void would help, it didn't
@JsonSerializable()
class PubSubResponse {
final bool success;
PubSubResponse(this.success);
factory PubSubResponse.fromJson(Map<String, dynamic> json) {
try {
return _$PubSubResponseFromJson(json);
} catch (e, s) {
print('PubSubResponse: Failed to parse json: $json');
rethrow;
}
}
Map<String, dynamic> toJson() => _$PubSubResponseToJson(this);
}
I've tried every combination return types and async keyword but I get the not compatible shape error if I use any sort of Future / async. I tried creating a Should I look at registering my own function target? If so is there any advice where to start with that? I've had a quick scout around but I couldn't see where they're registered. Thanks |
A little progress, it doesn't seem to be related to the Future/async. If I alter the package example to include the @CloudFunction()
GreetingResponse function(GreetingRequest request, RequestContext context) {
final name = request.name ?? 'World';
final json = GreetingResponse(salutation: 'Hello', name: name);
return json;
} With the same error:
My function & the package example both work without Why it builds on my local environment yet fails on docker & cloud run remains a mystery for now. All I can think was a dependency version discrepancy but I've pretty much locked all the dependency versions down to mirror cloud run and local. |
have you tried printing out the The only example I can think of is if the analyzer version has changed... |
diff --git a/examples/json/lib/functions.dart b/examples/json/lib/functions.dart
index 4213df4..802a158 100644
--- a/examples/json/lib/functions.dart
+++ b/examples/json/lib/functions.dart
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import 'dart:async';
+
import 'package:functions_framework/functions_framework.dart';
import 'package:json_annotation/json_annotation.dart';
@@ -59,7 +61,7 @@ class GreetingResponse {
}
@CloudFunction()
-GreetingResponse function(GreetingRequest request) {
+Future<GreetingResponse> function(GreetingRequest request) async {
final name = request.name ?? 'World';
final json = GreetingResponse(salutation: 'Hello', name: name);
return json; I tried changing up the example in the repro to make it work...and it's fine. I might could change this to support |
Hey @kevmoo the issue only occurs when adding a I've since modified my code not to require the context so this issue is not blocking me. I left the issue open because as far as I can tell, you should be able to use Happy for this issue to be closed or left open. |
Yep. Let's call it an enhancement! |
I tried modifying the integration test file and it works perfectly. I'm going to close this out. If you can modify the diff --git a/integration_test/bin/server.dart b/integration_test/bin/server.dart
index 6b155d0..ad074d1 100644
--- a/integration_test/bin/server.dart
+++ b/integration_test/bin/server.dart
@@ -61,6 +61,29 @@ FunctionTarget? _nameToFunctionTarget(String name) => switch (name) {
);
},
),
+ 'pubSubHandlerWithReplyAndContext' =>
+ JsonWithContextFunctionTarget.voidResult(
+ function_library.pubSubHandlerWithReplyAndContext,
+ (json) {
+ if (json is Map<String, dynamic>) {
+ try {
+ return function_library.PubSub.fromJson(json);
+ } catch (e, stack) {
+ throw BadRequestException(
+ 400,
+ 'There was an error parsing the provided JSON data.',
+ innerError: e,
+ innerStack: stack,
+ );
+ }
+ }
+ throw BadRequestException(
+ 400,
+ 'The provided JSON is not the expected type '
+ '`Map<String, dynamic>`.',
+ );
+ },
+ ),
'jsonHandler' => JsonWithContextFunctionTarget(
function_library.jsonHandler,
(json) {
diff --git a/integration_test/lib/src/json_handlers.dart b/integration_test/lib/src/json_handlers.dart
index 7e7e9db..016d5d6 100644
--- a/integration_test/lib/src/json_handlers.dart
+++ b/integration_test/lib/src/json_handlers.dart
@@ -24,6 +24,17 @@ void pubSubHandler(PubSub pubSub, RequestContext context) {
context.responseHeaders['multi'] = ['item1', 'item2'];
}
+@CloudFunction()
+Future<void> pubSubHandlerWithReplyAndContext(
+ PubSub pubSub,
+ RequestContext context,
+) async {
+ print('subscription: ${pubSub.subscription}');
+ context.logger.info('subscription: ${pubSub.subscription}');
+ context.responseHeaders['subscription'] = pubSub.subscription;
+ context.responseHeaders['multi'] = ['item1', 'item2'];
+}
+
@CloudFunction()
FutureOr<bool> jsonHandler(
Map<String, dynamic> request, |
I guess this IS a problem. Investigating more! |
It appears that |
Related to #464 Fixes http://b/348191438
Related to #464 Fixes http://b/348191438
I think I was able to work around the issue with It does, however, add a warning during build:
|
Thanks @mrmax99 – we have some really weird overlap of package features here causing problems. We don't want analyzer to "go back" because the perf win with the new implementation is great. I just need to carve out time to fix it the hard way. |
Hey, I've recently updated this package (0.4.3+1) and I'm having difficulty getting my async pub sub endpoints working again.
The issue seems to be with using async modifier, giving me
Not compatible with a supported function shape
error, this is my function decleration:Where as this works, but then I can't use all the async conveniences.
I'm sure I am missing something simple here? 😅 (apologies in advance...)
Error
bin/server.dart
lib/functions.dart
Thanks
The text was updated successfully, but these errors were encountered: