Skip to content
This repository was archived by the owner on Jan 13, 2022. It is now read-only.

Fix resumable upload error "There was a problem uploading your video" #1001

Merged
merged 3 commits into from
Nov 21, 2018

Conversation

phaizullin
Copy link
Contributor

Changed start_offset and end_offset from error code as written in documentation

@facebook-github-bot
Copy link

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@facebook-github-bot
Copy link

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks!

@yguedidi
Copy link
Contributor

@phaizullin Thanks for your contribution!
Why would you like include this behavior in the SDK? Especially that you can do the same in your code by allowing to throw and catching the exception

@phaizullin
Copy link
Contributor Author

@yguedidi Firstly, because it is mostly facebook internal error, it want to process another chunk (mostly random chunk) after processing current chunk, but uploadVideo method retry only current chunk and it returns same error 5 times via maxTriesTransfer method.
I think that main function of sdk is minimize interactions between user code and api. If api wants to upload another chunk it must do it.
Secondly, if I catch the error, I will need to re-implement Facebook class methods

@nasy
Copy link

nasy commented Jun 18, 2018

I am also experiencing the same problems, it would be nice for this fix to get merged.

@abhishekbh
Copy link

This is an important patch. What's the hold up in the merge or further comments?

@SammyK SammyK added this to the 5.6.3 milestone Jul 3, 2018
@SammyK
Copy link
Contributor

SammyK commented Jul 3, 2018

This seems to be a common issue so I'd be +1 for merging. For the record, the error message for 1363037 is:

There was a problem uploading your video. Please try uploading it again. error_data:{start_offset:0,end_offset:392695}

The recommendation is:

Returned when the server receives an invalid start offset from the client. Try to parse the start_offset and end_offset from error message and do a retry again.

@phaizullin & @yguedidi Assuming we merge this in - we should probably figure out how this impacts the max retires. This PR technically adds a non-deterministic outcome as there is an edge case where Graph returns the 1363037 sub code every time. Wudya think? :)

SammyK
SammyK previously requested changes Jul 3, 2018
Copy link
Contributor

@SammyK SammyK left a comment

Choose a reason for hiding this comment

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

@phaizullin Thanks for the PR! Can we also add a test to show this functionality works? Once we get these things tweaked, we can merge this in. :)

$chunk->getFile(),
$chunk->getUploadSessionId(),
$chunk->getVideoId(),
$e->getResponseData()['error']['error_data']['start_offset'],
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably do some isset() checks on this and the next line just in case Graph changes the error data structure it responds with.

@@ -121,6 +121,16 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow
throw $e;
}

if ($e->getSubErrorCode() === 1363037) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make 1363037 a class constant. :)

@SammyK SammyK modified the milestones: 5.6.3, 5.7.0 Jul 3, 2018
@yguedidi
Copy link
Contributor

yguedidi commented Jul 3, 2018

@phaizullin @SammyK I'm not that against this PR, I'm more against the implementation.

Let met explian: This solution looks more like a quick workaround to the issue.

How I conceptualy see it is more: you should catch a specific exception, that will give you access to a getRetryableChunk() or somethig like that, and you do what you want with it.

Enforcing an error handling internally looks bad to me. An SDK responsability is to provide the more detailed error, while handle it is user's code responsability: an SDK shouldn't has error no? :)

@phaizullin
Copy link
Contributor Author

@yguedidi @SammyK thanks for review. Please see the changes one more time)

@abhishekbh
Copy link

@yguedidi what you're saying makes sense, however the current pattern the SDK sets up with the "super" Facebook class is that the client has a minimum amount of information about the upload process.

If the FB SDK expects the calling client to handle chunks and errors (not a bad idea), it should expose more methods to allow an efficient way of doing this. The only public method in the Facebook class at the moment is "uploadVideo".

In the meanwhile, is there another recommendation on working around this issue?

@SammyK
Copy link
Contributor

SammyK commented Jul 6, 2018

@abhishekbh You could work directly with the Facebook\FileUpload\FacebookResumableUploader class to better handle these cases, but it doesn't have retry logic built in since that's handled by the main Facebook service class. I'd love hear if @yguedidi has a better suggestion for handling this particular case though. :)

@yguedidi
Copy link
Contributor

How I see things:

  • FacebookResumableUploader is the pure way, it does one try, if it fails, it throws
  • uploadVideo() is a helper function, a convenient way to do a full upload in one run, with cool feature like auto-retry.

I see the proposed fix (return the retryable chunk), as one of those cool feature, so I think it should live in the uploadVideo() function and be counted in the number of tries. :)
So basicly, what annoys me here is that it's the FacebookResumableUploader who handle that special case.

@phaizullin
Copy link
Contributor Author

@yguedidi It is't entirely clear from your words what changes in the PR are needed.

Copy link
Contributor

@yguedidi yguedidi left a comment

Choose a reason for hiding this comment

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

let's accept this solution and move forward! it still can be refactored for v6.
please rebase, fix review and update the changelog

$previousException = new FacebookResumableUploadException($message, $code);

$startOffset = isset($data['error']['error_data']['start_offset']) ?
$data['error']['error_data']['start_offset'] : null;
Copy link
Contributor

Choose a reason for hiding this comment

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

please keep this in the same line. BTW, you should cast to int the offset

$previousException->setStartOffset($startOffset);

$endOffset = isset($data['error']['error_data']['end_offset']) ?
$data['error']['error_data']['end_offset'] : null;
Copy link
Contributor

Choose a reason for hiding this comment

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

please keep this in the same line. BTW, you should cast to int the offset

protected $endOffset;

/**
* @return int
Copy link
Contributor

Choose a reason for hiding this comment

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

int|null

}

/**
* @param int $startOffset
Copy link
Contributor

Choose a reason for hiding this comment

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

int|null

}

/**
* @return int
Copy link
Contributor

Choose a reason for hiding this comment

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

int|null

}

/**
* @param int $endOffset
Copy link
Contributor

Choose a reason for hiding this comment

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

int|null

@@ -121,6 +121,16 @@ public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow
throw $e;
}

if (!is_null($preException->getStartOffset()) && !is_null($preException->getEndOffset())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer !== null instead of is_null


$chunk = new FacebookTransferChunk($this->file, '1', '2', '3', '4');
$newChunk = $uploader->transfer('/me/videos', $chunk);
$this->assertEquals('40', $newChunk->getStartOffset());
Copy link
Contributor

Choose a reason for hiding this comment

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

please assert also on the end ofset

@yguedidi
Copy link
Contributor

@phaizullin please rebase so that only your commit appear in the diff

@yguedidi
Copy link
Contributor

@phaizullin any news?

@phaizullin phaizullin reopened this Nov 20, 2018
@yguedidi yguedidi merged commit 4f1c91f into facebookarchive:5.x Nov 21, 2018
@yguedidi
Copy link
Contributor

Thank you @phaizullin

@yguedidi
Copy link
Contributor

And congrats for you first contribution to the SDK @phaizullin, I can't wait for your other pull requests!

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

Successfully merging this pull request may close these issues.

6 participants