使用 DocuSign REST 时收到 404 API
Getting a 404 when using the DocuSign REST API
在我的 Laravel 应用程序中,我发送带有此包裹的 DocuSign 信封:https://github.com/Tucker-Eric/Laravel-Docusign 效果很好。
此应用程序还使用“轮询”方法来检查对信封的更改。
为此,我从各种不同的模型中获取信封 ID,然后将这些 ID 传递给 DocuSign 的 listStatusChanges()
方法,该方法需要检查金额和一组信封 ID。
如果状态返回为已完成,我使用另一种方法getDocument()
下载已签名的文档。
这是每 15 分钟运行一次的作业。
<?php
namespace App\Jobs;
use App\CompanyActionPlan;
use App\CompanyOutcome;
use App\GrowthHubOutcome;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\CompanyRegistration;
use App\GrowthHubCompanyRegistration;
use App\Notifications\ActionPlanFormStatusUpdated;
use App\Notifications\GrowthHubOutcomesFormStatusUpdated;
use App\Notifications\GrowthHubRegistrationFormStatusUpdated;
use App\Notifications\OutcomesFormStatusUpdated;
use App\Notifications\RegistrationFormStatusUpdated;
use DocuSign;
use Carbon\Carbon;
use Storage;
use Log;
class PollDocuSignEnvelopes implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 3;
/**
* Create a new job instance.
*/
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// Create a new DocuSign client
$client = DocuSign::create();
// Create an empty array
$envelopeIds = [];
// Retrieve the unsigned envelopes from the company registrations
$actionPlanEnvelopes = CompanyActionPlan::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the action plans
$registrationEnvelopes = CompanyRegistration::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the outcomes
$outcomeEnvelopes = CompanyOutcome::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the lgh outcomes
$growthHubOutcomeEnvelopes = GrowthHubOutcome::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the lgh outcomes
$growthHubRegistrationEnvelopes = GrowthHubCompanyRegistration::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Merge the collection and send all envelope IDs to DocuSign for checking
$envelopeIds = array_merge(
$actionPlanEnvelopes,
$registrationEnvelopes,
$outcomeEnvelopes,
$growthHubOutcomeEnvelopes,
$growthHubRegistrationEnvelopes
);
// Only do anything if there are envelopes
if ($envelopeIds) {
$options = $client->envelopes->listStatusChangesOptions([
'count' => 25,
'envelope_ids' => $envelopeIds,
]);
$changes = $client->envelopes->listStatusChanges($options);
foreach ($changes['envelopes'] as $envelope) {
$this->checkActionPlans($envelope, $client);
$this->checkRegistrations($envelope, $client);
$this->checkOutcomes($envelope, $client);
$this->checkGrowthHubOutcomes($envelope, $client);
$this->checkGrowthHubRegistrations($envelope, $client);
}
}
}
/**
* Check the registration forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkRegistrations($envelope, $client)
{
$registration = CompanyRegistration::where('envelope_id', $envelope['envelope_id'])->first();
if ($registration) {
// Only attempt anything if that status is actually different to the previous attempt
if ($envelope['status'] != $registration->envelope_status) {
Log::info("SME Registration for company {$registration->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$registration->markAsVoided($voidedAt);
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$registration->markAsDeclined();
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$registration->markAsDelivered();
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/registrations/{$registration->id}/signed.pdf";
$this->retrieveSignedDocument($client, $registration->envelope_id, $filePath);
$registration->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
}
}
}
/**
* Check the action plan forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkActionPlans($envelope, $client)
{
$actionPlan = CompanyActionPlan::where('envelope_id', $envelope['envelope_id'])->first();
if ($actionPlan) {
if ($envelope['status'] != $actionPlan->envelope_status) {
Log::info("SME Action Plan for company {$actionPlan->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$actionPlan->markAsVoided($voidedAt);
$actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$actionPlan->markAsDeclined();
$actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$actionPlan->markAsDelivered();
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$completedAt = Carbon::parse($envelope['status_changed_date_time']);
$filePath = "/action-plans/{$actionPlan->id}/signed.pdf";
$signedDocument = $client->envelopes->getDocument(1, $actionPlan->envelope_id);
$documentContents = file_get_contents($signedDocument->getPathname());
Storage::disk('local')->put($filePath, $documentContents);
$actionPlan->markAsCompleted($completedAt, $filePath);
$actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
}
}
}
}
/**
* Check the registration forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkOutcomes($envelope, $client)
{
$outcome = CompanyOutcome::where('envelope_id', $envelope['envelope_id'])->first();
if ($outcome) {
if ($envelope['status'] != $outcome->envelope_status) {
Log::info("SME Outcomes for company {$outcome->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$outcome->markAsVoided($voidedAt);
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$outcome->markAsDeclined();
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$outcome->markAsDelivered();
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/outcomes/{$outcome->id}/signed.pdf";
$this->retrieveSignedDocument($client, $outcome->envelope_id, $filePath);
$outcome->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
}
}
}
/**
* Check the lgh outcomes forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkGrowthHubOutcomes($envelope, $client)
{
$outcome = GrowthHubOutcome::where('envelope_id', $envelope['envelope_id'])->first();
if ($outcome) {
if ($envelope['status'] != $outcome->envelope_status) {
Log::info("LGH SME Outcomes for company {$outcome->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$outcome->markAsVoided($voidedAt);
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$outcome->markAsDeclined();
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$outcome->markAsDelivered();
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/outcomes/growth-hub/{$outcome->id}/signed.pdf";
$this->retrieveSignedDocument($client, $outcome->envelope_id, $filePath);
$outcome->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
}
}
}
/**
* Check the lgh outcomes forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkGrowthHubRegistrations($envelope, $client)
{
$registration = GrowthHubCompanyRegistration::where('envelope_id', $envelope['envelope_id'])->first();
if ($registration) {
if ($envelope['status'] != $registration->envelope_status) {
Log::info("LGH SME Registration for company {$registration->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$registration->markAsVoided($voidedAt);
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$registration->markAsDeclined();
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$registration->markAsDelivered();
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/registrations/growth-hub/{$registration->id}/signed.pdf";
$this->retrieveSignedDocument($client, $registration->envelope_id, $filePath);
$registration->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
}
}
}
/**
* Retrieve the signed document from DocuSign and save it to storage at the given file path.
*
* @param [type] $client
* @param string $envelopeId
* @param string $filePath
*/
private function retrieveSignedDocument($client, $envelopeId, $filePath)
{
$signedDocument = $client->envelopes->getDocument(1, $envelopeId);
$documentContents = file_get_contents($signedDocument->getPathname());
Storage::disk('local')->put($filePath, $documentContents);
}
}
最近,就像今天一样,我开始收到来自 API 的 404。
这是堆栈跟踪。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>404 - File or directory not found.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
<div class="content-container"><fieldset>
<h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div>
</div>
</body>
</html>
{"url":"https://advice.newable.io","input":[],"userId":null,"email":null,"exception":"[object] (DocuSign\eSign\Client\ApiException(code: 404): Error while requesting server, received a non successful HTTP code [404] with response Body: <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"/>
<title>404 - File or directory not found.</title>
<style type=\"text/css\">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:\"trebuchet MS\", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id=\"header\"><h1>Server Error</h1></div>
<div id=\"content\">
<div class=\"content-container\"><fieldset>
<h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div>
</div>
</body>
</html>
at /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Client/ApiClient.php:330)
[stacktrace]
#0 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Api/EnvelopesApi.php(9328): DocuSign\eSign\Client\ApiClient->callApi('/v2/accounts/50...', 'GET', Array, '', Array, '\\DocuSign\\eSign...', '/v2/accounts/{a...')
#1 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Api/EnvelopesApi.php(9208): DocuSign\eSign\Api\EnvelopesApi->listStatusChangesWithHttpInfo('509375162', Object(DocuSign\eSign\Api\EnvelopesApi\ListStatusChangesOptions))
#2 [internal function]: DocuSign\eSign\Api\EnvelopesApi->listStatusChanges('509375162', Object(DocuSign\eSign\Api\EnvelopesApi\ListStatusChangesOptions))
#3 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/tucker-eric/docusign-rest-client/src/Api/BaseApi.php(76): call_user_func_array(Array, Array)
#4 /homepages/45/d641872465/htdocs/sites/ita-portal/app/Jobs/PollDocuSignEnvelopes.php(107): DocuSign\Rest\Api\BaseApi->__call('listStatusChang...', Array)
#5 [internal function]: App\Jobs\PollDocuSignEnvelopes->handle()
#6 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#7 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#8 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#9 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#10 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#11 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\Container\Container->call(Array)
#12 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#13 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#14 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#15 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(83): Illuminate\Bus\Dispatcher->dispatchNow(Object(App\Jobs\PollDocuSignEnvelopes), false)
#16 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\Queue\CallQueuedHandler->Illuminate\Queue\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#17 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#18 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(85): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#19 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(59): Illuminate\Queue\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\Queue\Jobs\DatabaseJob), Object(App\Jobs\PollDocuSignEnvelopes))
#20 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\DatabaseJob), Array)
#21 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(368): Illuminate\Queue\Jobs\Job->fire()
#22 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(314): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions))
#23 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(134): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob), 'database', Object(Illuminate\Queue\WorkerOptions))
#24 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\Queue\Worker->daemon('database', 'default', Object(Illuminate\Queue\WorkerOptions))
#25 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'default')
#26 [internal function]: Illuminate\Queue\Console\WorkCommand->handle()
#27 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#28 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#29 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#30 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#31 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#32 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Command.php(134): Illuminate\Container\Container->call(Array)
#33 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Command/Command.php(255): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#34 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#35 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(1005): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#36 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(271): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#37 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(147): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#38 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#39 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#40 /homepages/45/d641872465/htdocs/sites/ita-portal/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#41 {main}
"}
我该如何调试它?
(我在 DocuSign Sandox 中有一个相同的设置,它按预期工作)。
我知道此调用特别是 returns 404 响应的唯一原因是请求是否包含特定数量的特定 envelopeId 列表。我们 SDK 的旧版本和许多客户解决方案将这些 envelopeIds 以 URL 参数的形式添加到请求中。我在测试时发现,当我接近或超过 49 个信封时,响应从 200 变为 404。
查看提供的代码,我看到了这个:
// Only do anything if there are envelopes
if ($envelopeIds) {
$options = $client->envelopes->listStatusChangesOptions([
'count' => 25,
'envelope_ids' => $envelopeIds,
]);
$changes = $client->envelopes->listStatusChanges($options);
你能确认这里包含的信封总数吗?如果数字约为 49,则可能是罪魁祸首,这意味着您需要添加额外的检查以限制传递到 listStatusChangesOptions 对象的 envelopeId 的总数。
在我的 Laravel 应用程序中,我发送带有此包裹的 DocuSign 信封:https://github.com/Tucker-Eric/Laravel-Docusign 效果很好。
此应用程序还使用“轮询”方法来检查对信封的更改。
为此,我从各种不同的模型中获取信封 ID,然后将这些 ID 传递给 DocuSign 的 listStatusChanges()
方法,该方法需要检查金额和一组信封 ID。
如果状态返回为已完成,我使用另一种方法getDocument()
下载已签名的文档。
这是每 15 分钟运行一次的作业。
<?php
namespace App\Jobs;
use App\CompanyActionPlan;
use App\CompanyOutcome;
use App\GrowthHubOutcome;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\CompanyRegistration;
use App\GrowthHubCompanyRegistration;
use App\Notifications\ActionPlanFormStatusUpdated;
use App\Notifications\GrowthHubOutcomesFormStatusUpdated;
use App\Notifications\GrowthHubRegistrationFormStatusUpdated;
use App\Notifications\OutcomesFormStatusUpdated;
use App\Notifications\RegistrationFormStatusUpdated;
use DocuSign;
use Carbon\Carbon;
use Storage;
use Log;
class PollDocuSignEnvelopes implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 3;
/**
* Create a new job instance.
*/
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// Create a new DocuSign client
$client = DocuSign::create();
// Create an empty array
$envelopeIds = [];
// Retrieve the unsigned envelopes from the company registrations
$actionPlanEnvelopes = CompanyActionPlan::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the action plans
$registrationEnvelopes = CompanyRegistration::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the outcomes
$outcomeEnvelopes = CompanyOutcome::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the lgh outcomes
$growthHubOutcomeEnvelopes = GrowthHubOutcome::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Retrieve the unsigned envelopes from the lgh outcomes
$growthHubRegistrationEnvelopes = GrowthHubCompanyRegistration::select('envelope_id')
->unsignedEnvelope()
->unvoidedEnvelope()
->pluck('envelope_id')
->toArray();
// Merge the collection and send all envelope IDs to DocuSign for checking
$envelopeIds = array_merge(
$actionPlanEnvelopes,
$registrationEnvelopes,
$outcomeEnvelopes,
$growthHubOutcomeEnvelopes,
$growthHubRegistrationEnvelopes
);
// Only do anything if there are envelopes
if ($envelopeIds) {
$options = $client->envelopes->listStatusChangesOptions([
'count' => 25,
'envelope_ids' => $envelopeIds,
]);
$changes = $client->envelopes->listStatusChanges($options);
foreach ($changes['envelopes'] as $envelope) {
$this->checkActionPlans($envelope, $client);
$this->checkRegistrations($envelope, $client);
$this->checkOutcomes($envelope, $client);
$this->checkGrowthHubOutcomes($envelope, $client);
$this->checkGrowthHubRegistrations($envelope, $client);
}
}
}
/**
* Check the registration forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkRegistrations($envelope, $client)
{
$registration = CompanyRegistration::where('envelope_id', $envelope['envelope_id'])->first();
if ($registration) {
// Only attempt anything if that status is actually different to the previous attempt
if ($envelope['status'] != $registration->envelope_status) {
Log::info("SME Registration for company {$registration->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$registration->markAsVoided($voidedAt);
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$registration->markAsDeclined();
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$registration->markAsDelivered();
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/registrations/{$registration->id}/signed.pdf";
$this->retrieveSignedDocument($client, $registration->envelope_id, $filePath);
$registration->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$registration->user->notify(new RegistrationFormStatusUpdated($registration));
}
}
}
}
/**
* Check the action plan forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkActionPlans($envelope, $client)
{
$actionPlan = CompanyActionPlan::where('envelope_id', $envelope['envelope_id'])->first();
if ($actionPlan) {
if ($envelope['status'] != $actionPlan->envelope_status) {
Log::info("SME Action Plan for company {$actionPlan->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$actionPlan->markAsVoided($voidedAt);
$actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$actionPlan->markAsDeclined();
$actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$actionPlan->markAsDelivered();
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$completedAt = Carbon::parse($envelope['status_changed_date_time']);
$filePath = "/action-plans/{$actionPlan->id}/signed.pdf";
$signedDocument = $client->envelopes->getDocument(1, $actionPlan->envelope_id);
$documentContents = file_get_contents($signedDocument->getPathname());
Storage::disk('local')->put($filePath, $documentContents);
$actionPlan->markAsCompleted($completedAt, $filePath);
$actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
}
}
}
}
/**
* Check the registration forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkOutcomes($envelope, $client)
{
$outcome = CompanyOutcome::where('envelope_id', $envelope['envelope_id'])->first();
if ($outcome) {
if ($envelope['status'] != $outcome->envelope_status) {
Log::info("SME Outcomes for company {$outcome->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$outcome->markAsVoided($voidedAt);
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$outcome->markAsDeclined();
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$outcome->markAsDelivered();
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/outcomes/{$outcome->id}/signed.pdf";
$this->retrieveSignedDocument($client, $outcome->envelope_id, $filePath);
$outcome->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
}
}
}
}
/**
* Check the lgh outcomes forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkGrowthHubOutcomes($envelope, $client)
{
$outcome = GrowthHubOutcome::where('envelope_id', $envelope['envelope_id'])->first();
if ($outcome) {
if ($envelope['status'] != $outcome->envelope_status) {
Log::info("LGH SME Outcomes for company {$outcome->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$outcome->markAsVoided($voidedAt);
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$outcome->markAsDeclined();
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$outcome->markAsDelivered();
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/outcomes/growth-hub/{$outcome->id}/signed.pdf";
$this->retrieveSignedDocument($client, $outcome->envelope_id, $filePath);
$outcome->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
}
}
}
}
/**
* Check the lgh outcomes forms against the returned changes from DocuSign
*
* @param string $envelope
* @param mixed $client
*
*/
private function checkGrowthHubRegistrations($envelope, $client)
{
$registration = GrowthHubCompanyRegistration::where('envelope_id', $envelope['envelope_id'])->first();
if ($registration) {
if ($envelope['status'] != $registration->envelope_status) {
Log::info("LGH SME Registration for company {$registration->company_name} was {$envelope['status']}.");
if ($envelope['status'] == 'voided') {
$voidedAt = Carbon::parse($envelope['voided_date_time']);
$registration->markAsVoided($voidedAt);
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
// If the document has been declined
if ($envelope['status'] == 'declined') {
$registration->markAsDeclined();
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
// If the document has been delivered
if ($envelope['status'] == 'delivered') {
$registration->markAsDelivered();
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
// If the envelope is complete, timestamp it, notify the creator and grab the signed document
if ($envelope['status'] == 'completed') {
$filePath = "/registrations/growth-hub/{$registration->id}/signed.pdf";
$this->retrieveSignedDocument($client, $registration->envelope_id, $filePath);
$registration->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);
$registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
}
}
}
}
/**
* Retrieve the signed document from DocuSign and save it to storage at the given file path.
*
* @param [type] $client
* @param string $envelopeId
* @param string $filePath
*/
private function retrieveSignedDocument($client, $envelopeId, $filePath)
{
$signedDocument = $client->envelopes->getDocument(1, $envelopeId);
$documentContents = file_get_contents($signedDocument->getPathname());
Storage::disk('local')->put($filePath, $documentContents);
}
}
最近,就像今天一样,我开始收到来自 API 的 404。
这是堆栈跟踪。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>404 - File or directory not found.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
<div class="content-container"><fieldset>
<h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div>
</div>
</body>
</html>
{"url":"https://advice.newable.io","input":[],"userId":null,"email":null,"exception":"[object] (DocuSign\eSign\Client\ApiException(code: 404): Error while requesting server, received a non successful HTTP code [404] with response Body: <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"/>
<title>404 - File or directory not found.</title>
<style type=\"text/css\">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:\"trebuchet MS\", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id=\"header\"><h1>Server Error</h1></div>
<div id=\"content\">
<div class=\"content-container\"><fieldset>
<h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div>
</div>
</body>
</html>
at /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Client/ApiClient.php:330)
[stacktrace]
#0 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Api/EnvelopesApi.php(9328): DocuSign\eSign\Client\ApiClient->callApi('/v2/accounts/50...', 'GET', Array, '', Array, '\\DocuSign\\eSign...', '/v2/accounts/{a...')
#1 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Api/EnvelopesApi.php(9208): DocuSign\eSign\Api\EnvelopesApi->listStatusChangesWithHttpInfo('509375162', Object(DocuSign\eSign\Api\EnvelopesApi\ListStatusChangesOptions))
#2 [internal function]: DocuSign\eSign\Api\EnvelopesApi->listStatusChanges('509375162', Object(DocuSign\eSign\Api\EnvelopesApi\ListStatusChangesOptions))
#3 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/tucker-eric/docusign-rest-client/src/Api/BaseApi.php(76): call_user_func_array(Array, Array)
#4 /homepages/45/d641872465/htdocs/sites/ita-portal/app/Jobs/PollDocuSignEnvelopes.php(107): DocuSign\Rest\Api\BaseApi->__call('listStatusChang...', Array)
#5 [internal function]: App\Jobs\PollDocuSignEnvelopes->handle()
#6 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#7 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#8 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#9 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#10 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#11 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\Container\Container->call(Array)
#12 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\Bus\Dispatcher->Illuminate\Bus\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#13 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#14 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#15 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(83): Illuminate\Bus\Dispatcher->dispatchNow(Object(App\Jobs\PollDocuSignEnvelopes), false)
#16 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\Queue\CallQueuedHandler->Illuminate\Queue\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#17 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(App\Jobs\PollDocuSignEnvelopes))
#18 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(85): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#19 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(59): Illuminate\Queue\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\Queue\Jobs\DatabaseJob), Object(App\Jobs\PollDocuSignEnvelopes))
#20 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\DatabaseJob), Array)
#21 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(368): Illuminate\Queue\Jobs\Job->fire()
#22 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(314): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions))
#23 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(134): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob), 'database', Object(Illuminate\Queue\WorkerOptions))
#24 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\Queue\Worker->daemon('database', 'default', Object(Illuminate\Queue\WorkerOptions))
#25 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'default')
#26 [internal function]: Illuminate\Queue\Console\WorkCommand->handle()
#27 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#28 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#29 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#30 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#31 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#32 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Command.php(134): Illuminate\Container\Container->call(Array)
#33 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Command/Command.php(255): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#34 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#35 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(1005): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#36 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(271): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#37 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(147): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#38 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#39 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#40 /homepages/45/d641872465/htdocs/sites/ita-portal/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#41 {main}
"}
我该如何调试它?
(我在 DocuSign Sandox 中有一个相同的设置,它按预期工作)。
我知道此调用特别是 returns 404 响应的唯一原因是请求是否包含特定数量的特定 envelopeId 列表。我们 SDK 的旧版本和许多客户解决方案将这些 envelopeIds 以 URL 参数的形式添加到请求中。我在测试时发现,当我接近或超过 49 个信封时,响应从 200 变为 404。
查看提供的代码,我看到了这个:
// Only do anything if there are envelopes
if ($envelopeIds) {
$options = $client->envelopes->listStatusChangesOptions([
'count' => 25,
'envelope_ids' => $envelopeIds,
]);
$changes = $client->envelopes->listStatusChanges($options);
你能确认这里包含的信封总数吗?如果数字约为 49,则可能是罪魁祸首,这意味着您需要添加额外的检查以限制传递到 listStatusChangesOptions 对象的 envelopeId 的总数。