Skip to content

gcloud logging more#182

Draft
kevmoo wants to merge 2 commits into
mainfrom
gcloud_logging_more
Draft

gcloud logging more#182
kevmoo wants to merge 2 commits into
mainfrom
gcloud_logging_more

Conversation

@kevmoo

@kevmoo kevmoo commented May 13, 2026

Copy link
Copy Markdown
Collaborator
  • Refactor logging and environment parsing to use package:google_cloud
  • cleanup logging!

kevmoo added 2 commits April 6, 2026 17:30
Integrates `package:google_cloud` for structured logging, trace context, and standard environment variables.

Details:
- Update `Logger` to extend `CloudLogger` from `package:google_cloud`.
- Replace custom trace context parsing and zone keys with `TraceContextData` and standard constants.
- Update `fireUp` server startup to use `TraceContextData.tryParse`.
- Remove custom `removeCircular` logic and related tests (offloaded to `google_cloud`).
- Upgrade `google_cloud_storage` to `^0.6.0` and add `google_cloud` dependency.
- Modernize logging calls throughout (`logger.warning` with `stackTrace` etc).
- Remove obsolete `server_test.dart` for custom trace parsing.
- Use standard constants for environment variables (e.g., `serviceEnvironmentVariable`, `projectIdEnvironmentVariableOptions`).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the Firebase Functions error handling and logging infrastructure, replacing custom error classes with HttpResponseException from package:google_cloud and integrating structured logging. Key changes include updating callable and event-triggered function handlers to use the new exception type, removing deprecated error logging utilities, and updating the server startup logic to use serveHandler. The review feedback highlights critical issues, including a potential runtime error due to a missing toJson method on HttpResponseException, a regression in observability where exceptions were being swallowed, a broken dependency override path in pubspec.yaml, a missing import for currentLogger, and a suggestion to utilize the FunctionsErrorCode enum for consistent error reporting.

return createNonStreamingResponse(result);
} on HttpsError catch (e) {
} on HttpResponseException catch (e) {
final errorPayload = e.toJson();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

There are two issues here:

  1. HttpResponseException from package:google_cloud does not have a toJson() method, which will cause a runtime NoSuchMethodError.
  2. The Firebase Callable protocol requires error responses to be wrapped in a top-level error key (e.g., {"error": {"status": "...", "message": "..."}}). Simply returning the result of a hypothetical toJson() would likely violate this spec.

You should manually construct the error payload using the FunctionsErrorCode enum provided at the end of this file to map the HTTP status code to the appropriate string status.

Suggested change
final errorPayload = e.toJson();
} on HttpResponseException catch (e) {
final errorPayload = {
'error': {
'status': FunctionsErrorCode.values
.firstWhere((v) => v.httpStatusCode == e.statusCode,
orElse: () => FunctionsErrorCode.unknown)
.value
.toUpperCase()
.replaceAll('-', '_'),
'message': e.message ?? 'Unknown error',
}
};

Comment on lines +305 to +308
} catch (e) {
final errorPayload = {
'error': {'status': 'INTERNAL', 'message': 'Internal error'},
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This catch block for unexpected errors is a regression in observability. It swallows the exception e and its stack trace without logging them, making it impossible to diagnose server-side failures. It should also include the stackTrace parameter in the catch clause and use currentLogger.error to record the failure details before returning the generic internal error response to the client.

    } catch (e, stackTrace) {
      currentLogger.error('Unexpected error in callable function',
          error: e, stackTrace: stackTrace);
      final errorPayload = {
        'error': {'status': 'INTERNAL', 'message': 'Internal error'},
      };

Comment thread pubspec.yaml
Comment on lines +72 to +73
google_cloud:
path: /Users/kevmoo/github/google-cloud-dart/pkgs/google_cloud

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The dependency_overrides section contains a local file system path (/Users/kevmoo/...). This will cause the build to fail in CI environments and for any other developer who does not have the exact same directory structure. This override should be removed before merging.

import 'dart:async';
import 'dart:convert';

import 'package:google_cloud/http_serving.dart';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The currentLogger from package:google_cloud is used in several places in this PR, but the necessary import is missing in this file. This will lead to compilation errors when trying to use currentLogger for error logging in the callable handlers.

Suggested change
import 'package:google_cloud/http_serving.dart';
import 'package:google_cloud/google_cloud.dart';
import 'package:google_cloud/http_serving.dart';

Comment on lines +327 to +368
enum FunctionsErrorCode {
// NOTE: These are ordered so that the first error code with a given HTTP
// status code is the one that is used when mapping from HTTP status codes.
ok('ok', 'OK', 200),
invalidArgument('invalid-argument', 'Invalid argument', 400),
failedPrecondition('failed-precondition', 'Failed precondition', 400),
outOfRange('out-of-range', 'Value out of range', 400),
unauthenticated('unauthenticated', 'Unauthenticated', 401),
permissionDenied('permission-denied', 'Permission denied', 403),
notFound('not-found', 'Resource not found', 404),
alreadyExists('already-exists', 'Resource already exists', 409),
aborted('aborted', 'Operation aborted', 409),
resourceExhausted('resource-exhausted', 'Resource exhausted', 429),
cancelled('cancelled', 'Request was cancelled', 499),
internal('internal', 'Internal error', 500),
unknown('unknown', 'Unknown error occurred', 500),
dataLoss('data-loss', 'Data loss', 500),
unimplemented('unimplemented', 'Operation not implemented', 501),
unavailable('unavailable', 'Service unavailable', 503),
deadlineExceeded('deadline-exceeded', 'Deadline exceeded', 504);

const FunctionsErrorCode(this.value, this.message, this.httpStatusCode);

/// The string value used in JSON serialization.
final String value;

/// The default human-readable message for this error code.
final String message;

/// The corresponding HTTP status code.
final int httpStatusCode;

/// Maps an error code value string to the corresponding enum.
static FunctionsErrorCode? fromValue(String value) {
for (final code in FunctionsErrorCode.values) {
if (code.value == value) {
return code;
}
}
return null;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The FunctionsErrorCode enum is defined here but is currently unused within this file. While it might be intended for public export, it should be utilized in the error handling logic of _handleCallable to ensure consistent error reporting that adheres to the Firebase Callable specification, or removed if it is truly redundant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant