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

FR: [FB Messaging] Expose full FirebaseError #576

Open
AustinHunt opened this issue Aug 10, 2023 · 3 comments
Open

FR: [FB Messaging] Expose full FirebaseError #576

AustinHunt opened this issue Aug 10, 2023 · 3 comments

Comments

@AustinHunt
Copy link

[REQUIRED] Step 2: Describe your environment

  • Operating System version: macOS
  • Firebase SDK version: latest
  • Library version: v4.12.0
  • Firebase Product: messaging

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

The messaging api returns robust error codes to tell your application what went wrong with the server. This go-lang library abstracts this away and only gives you the following struct: https://github.com/firebase/firebase-admin-go/blob/v4.12.0/messaging/messaging_batch.go#L78

This makes it impossible to react to different kinds of failures when calling sendBatch. In my case, I want to remove invalid device tokens from my database.

If the lib could return this struct (

type FirebaseError struct {
) instead of the standard error the issue would be resolved.

Relevant Code:

func (firebaseSender *FirebaseSender) cleanupDevices(ctx context.Context, batchResponse *messaging.BatchResponse) {
	if batchResponse.FailureCount == 0 {
		return
	}

	for _, sendResponse := range batchResponse.Responses {
		logger.Debug(sendResponse.Error) // Expose ErrorCode here so that I can switch and deal with different kinds of failures.
	}
}

The internal library has the data structure I need, but it is in the internal library and unavailable to other modules.

// ErrorCode represents the platform-wide error codes that can be raised by
// Admin SDK APIs.
type ErrorCode string

const (
	// InvalidArgument is a OnePlatform error code.
	InvalidArgument ErrorCode = "INVALID_ARGUMENT"

	// FailedPrecondition is a OnePlatform error code.
	FailedPrecondition ErrorCode = "FAILED_PRECONDITION"

	// OutOfRange is a OnePlatform error code.
	OutOfRange ErrorCode = "OUT_OF_RANGE"

	// Unauthenticated is a OnePlatform error code.
	Unauthenticated ErrorCode = "UNAUTHENTICATED"

	// PermissionDenied is a OnePlatform error code.
	PermissionDenied ErrorCode = "PERMISSION_DENIED"

	// NotFound is a OnePlatform error code.
	NotFound ErrorCode = "NOT_FOUND"

	// Conflict is a custom error code that represents HTTP 409 responses.
	//
	// OnePlatform APIs typically respond with ABORTED or ALREADY_EXISTS explicitly. But a few
	// old APIs send HTTP 409 Conflict without any additional details to distinguish between the two
	// cases. For these we currently use this error code. As more APIs adopt OnePlatform conventions
	// this will become less important.
	Conflict ErrorCode = "CONFLICT"

	// Aborted is a OnePlatform error code.
	Aborted ErrorCode = "ABORTED"

	// AlreadyExists is a OnePlatform error code.
	AlreadyExists ErrorCode = "ALREADY_EXISTS"

	// ResourceExhausted is a OnePlatform error code.
	ResourceExhausted ErrorCode = "RESOURCE_EXHAUSTED"

	// Cancelled is a OnePlatform error code.
	Cancelled ErrorCode = "CANCELLED"

	// DataLoss is a OnePlatform error code.
	DataLoss ErrorCode = "DATA_LOSS"

	// Unknown is a OnePlatform error code.
	Unknown ErrorCode = "UNKNOWN"

	// Internal is a OnePlatform error code.
	Internal ErrorCode = "INTERNAL"

	// Unavailable is a OnePlatform error code.
	Unavailable ErrorCode = "UNAVAILABLE"

	// DeadlineExceeded is a OnePlatform error code.
	DeadlineExceeded ErrorCode = "DEADLINE_EXCEEDED"
)

// FirebaseError is an error type containing an error code string.
type FirebaseError struct {
	ErrorCode ErrorCode
	String    string
	Response  *http.Response
	Ext       map[string]interface{}
}

func (fe *FirebaseError) Error() string {
	return fe.String
}
@goodje
Copy link

goodje commented Sep 3, 2023

I'm using Firebase Auth, when it fails to verify a token, Im able to know the reason from the message, however, because the ErrorCode and Ext fields are not exposed, I'm not able to handle each case programmaticlly.

So yep, it will be really helpful to expose the fields and error codes, please add the feature, thank you!

@breml
Copy link

breml commented Feb 27, 2024

I also have troubles with the FirebaseError being in an internal package, since there is no way to use it in e.g. errors.Is or errors.As (the idiomatic way to compare errors) as well as to create such an error on my own (e.g. in a mock used in unit tests), which makes it unnecessarily hard to test code using this module for interactions with Firebase. Since the FirebaseError is returned from the methods provided by this module, I consider it as part of the API and therefore it should be exposed.
The errorutils package is somewhat helpful, but to me, it looks more like a workaround.

@boristomic
Copy link

@lahirumaramba I see you are most active maintainer so just wanted to ask if this is something you are considering to expose?

It would be extremely useful like others mentioned already.

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

No branches or pull requests

5 participants