Skip to content

Commit 8fef374

Browse files
authored
Merge pull request #378 from firebase/lk/403-errors
Better handle errors when uploading binary
2 parents b459a1c + 7ff45bc commit 8fef374

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

lib/fastlane/plugin/firebase_app_distribution/actions/firebase_app_distribution_action.rb

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def self.run(params)
5656

5757
binary_type = binary_type_from_path(binary_path)
5858
UI.message("📡 Uploading the #{binary_type}.")
59-
operation = upload_binary(app_name, binary_path, client, timeout)
59+
operation = upload_binary(app_name, binary_path, binary_type, client, timeout)
6060
UI.message("🕵️ Validating upload…")
6161
release = poll_upload_release_operation(client, operation, binary_type)
6262

@@ -268,7 +268,7 @@ def self.poll_upload_release_operation(client, operation, binary_type)
268268
extract_release(operation)
269269
end
270270

271-
def self.upload_binary(app_name, binary_path, client, timeout)
271+
def self.upload_binary(app_name, binary_path, binary_type, client, timeout)
272272
options = Google::Apis::RequestOptions.new
273273
options.max_elapsed_time = timeout # includes retries (default = no retries)
274274
options.header = {
@@ -282,12 +282,21 @@ def self.upload_binary(app_name, binary_path, client, timeout)
282282
# standard http call instead and convert it to a long running object
283283
# https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-firebaseappdistribution_v1/lib/google/apis/firebaseappdistribution_v1/service.rb#L79
284284
# TODO(kbolay): Prefer client.upload_medium
285-
response = client.http(
286-
:post,
287-
"https://firebaseappdistribution.googleapis.com/upload/v1/#{app_name}/releases:upload",
288-
body: File.open(binary_path, 'rb'),
289-
options: options
290-
)
285+
response = begin
286+
client.http(
287+
:post,
288+
"https://firebaseappdistribution.googleapis.com/upload/v1/#{app_name}/releases:upload",
289+
body: File.open(binary_path, 'rb'),
290+
options: options
291+
)
292+
rescue Google::Apis::Error => err
293+
case err.status_code.to_i
294+
when 403
295+
UI.crash!(ErrorMessage::PERMISSION_DENIED_ERROR)
296+
else
297+
UI.crash!("#{ErrorMessage.upload_binary_error(binary_type)} (#{err}, status_code: #{err.status_code})")
298+
end
299+
end
291300

292301
Google::Apis::FirebaseappdistributionV1::GoogleLongrunningOperation.from_json(response)
293302
end

lib/fastlane/plugin/firebase_app_distribution/helper/firebase_app_distribution_error_message.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ module ErrorMessage
44
SERVICE_CREDENTIALS_NOT_FOUND = "Service credentials file does not exist. Please check the service credentials path and try again."
55
PARSE_SERVICE_CREDENTIALS_ERROR = "Failed to extract service account information from the service credentials file."
66
PARSE_FIREBASE_TOOLS_JSON_ERROR = "Encountered error parsing json file. Ensure the firebase-tools.json file is formatted correctly."
7+
PERMISSION_DENIED_ERROR = "The authenticated user does not have the required permissions on the Firebase project"
8+
UPLOAD_BINARY_ERROR = "App Distribution halted because it had a problem uploading the app binary."
79
UPLOAD_RELEASE_NOTES_ERROR = "App Distribution halted because it had a problem uploading release notes."
810
UPLOAD_TESTERS_ERROR = "App Distribution halted because it had a problem adding testers/groups."
911
GET_RELEASE_TIMEOUT = "App Distribution failed to fetch release information."

spec/firebase_app_distribution_action_spec.rb

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def stub_get_aab_info(integration_state = 'INTEGRATED')
307307
end
308308
end
309309

310-
describe 'with a successful upload' do
310+
describe 'with a binary file available' do
311311
let(:fake_binary_contents) { "Hello World" }
312312
let(:fake_binary) { double("Binary") }
313313

@@ -319,6 +319,26 @@ def stub_get_aab_info(integration_state = 'INTEGRATED')
319319
.and_return(fake_binary_contents)
320320
end
321321

322+
it 'raises permission denied error if upload returns a 403', :focus do
323+
allow_any_instance_of(V1Api::FirebaseAppDistributionService)
324+
.to receive(:http)
325+
.and_raise(Google::Apis::Error.new('error', status_code: '403'))
326+
327+
expect do
328+
action.run(params)
329+
end.to raise_error(ErrorMessage::PERMISSION_DENIED_ERROR)
330+
end
331+
332+
it 'raises error with status code if upload returns an unexpected error', :focus do
333+
allow_any_instance_of(V1Api::FirebaseAppDistributionService)
334+
.to receive(:http)
335+
.and_raise(Google::Apis::Error.new({}, status_code: '404'))
336+
337+
expect do
338+
action.run(params)
339+
end.to raise_error(/404/)
340+
end
341+
322342
it 'crashes if it exceeds polling threshold' do
323343
stub_const('Fastlane::Actions::FirebaseAppDistributionAction::UPLOAD_MAX_POLLING_RETRIES', 0)
324344
allow_any_instance_of(V1Api::FirebaseAppDistributionService)

0 commit comments

Comments
 (0)