Skip to content

Commit 758367d

Browse files
LuborRodRodion Liuborets
andauthored
SDK-2143: Add error code and description in failure receipt message (#284)
* SDK-2143: Add error code and description in failure receipt message * SDK-2143 Add more info to ActivityDetailsException * SDK-2143 Small fix for error details * SDK-2143 Delete unnecessary method * SDK-2143 Delete unnecessary method2 Co-authored-by: Rodion Liuborets <[email protected]>
1 parent 46f5686 commit 758367d

File tree

7 files changed

+84
-31
lines changed

7 files changed

+84
-31
lines changed

examples/profile/app/Http/Controllers/DbsCheckController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ public function show(YotiClient $client)
1616
'trust_framework' => 'UK_TFIDA',
1717
'scheme' => [
1818
'type' => 'DBS',
19-
'objective' => 'STANDARD'
19+
'objective' => 'BASIC'
2020
]
2121
])
2222
->build();
2323

2424
$dynamicScenario = (new DynamicScenarioBuilder())
25-
->withCallbackEndpoint("/account/connect")
25+
->withCallbackEndpoint("/profile")
2626
->withPolicy($dynamicPolicy)
2727
->withSubject((object)[
2828
'subject_id' => "some_subject_id_string"

src/Exception/ActivityDetailsException.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,47 @@
44

55
namespace Yoti\Exception;
66

7+
use Psr\Http\Message\ResponseInterface;
78
use Yoti\Exception\base\YotiException;
9+
use Yoti\Util\Json;
810

911
class ActivityDetailsException extends YotiException
1012
{
13+
/**
14+
* @var array<string, mixed>|null
15+
*/
16+
private $responseBody;
17+
18+
/**
19+
* @param string $message
20+
* @param ResponseInterface|null $response
21+
* @param array<string, mixed>|null $responseBody
22+
* @param \Throwable|null $previous
23+
*/
24+
public function __construct(
25+
$message = "",
26+
?ResponseInterface $response = null,
27+
?array $responseBody = null,
28+
\Throwable $previous = null
29+
) {
30+
parent::__construct($message, $response, $previous);
31+
32+
$this->responseBody = $responseBody;
33+
}
34+
35+
/**
36+
* @return string
37+
*/
38+
public function getReceiptErrorDetails(): string
39+
{
40+
$result = [];
41+
if (!is_null($this->responseBody)) {
42+
$result['receipt_id'] = $this->responseBody['receipt']['receipt_id'] ?? ' ';
43+
if (isset($this->responseBody['error_details'])) {
44+
$result['description'] = $this->responseBody['error_details']['description'] ?? ' ';
45+
$result['error_code'] = $this->responseBody['error_details']['error_code'] ?? ' ';
46+
}
47+
}
48+
return Json::encode($result);
49+
}
1150
}

src/Profile/Receipt.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Receipt
2323
private const ATTR_WRAPPED_RECEIPT_KEY = 'wrapped_receipt_key';
2424
private const ATTR_OTHER_PARTY_PROFILE_CONTENT = 'other_party_profile_content';
2525
private const ATTR_EXTRA_DATA_CONTENT = 'extra_data_content';
26+
private const ATTR_ERROR_DETAILS = 'error_details';
2627

2728
/**
2829
* @var array<string, mixed>
@@ -45,8 +46,6 @@ public function __construct(array $receiptData, ?LoggerInterface $logger = null)
4546
{
4647
$this->logger = $logger ?? new Logger();
4748

48-
$this->validateReceipt($receiptData);
49-
5049
$this->receiptData = $receiptData;
5150
}
5251

@@ -165,18 +164,4 @@ private function decryptAttribute(string $attributeName, PemFile $pemFile): ?str
165164
$pemFile
166165
);
167166
}
168-
169-
/**
170-
* Check Wrapped_receipt_key exists and is not NULL.
171-
*
172-
* @param array<string, mixed> $receiptData
173-
*
174-
* @throws ReceiptException
175-
*/
176-
private function validateReceipt(array $receiptData): void
177-
{
178-
if (!isset($receiptData[self::ATTR_WRAPPED_RECEIPT_KEY])) {
179-
throw new ReceiptException('Wrapped Receipt key attr is missing');
180-
}
181-
}
182167
}

src/Profile/Service.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ public function getActivityDetails(string $encryptedConnectToken): ActivityDetai
8888

8989
// Check response was successful
9090
if ($receipt->getSharingOutcome() !== self::OUTCOME_SUCCESS) {
91-
throw new ActivityDetailsException('Outcome was unsuccessful', $response);
91+
throw new ActivityDetailsException(
92+
'Sharing activity unsuccessful for ' . $receipt->getReceiptId() . ' '
93+
. $result['error_details']['description'] . ' '
94+
. $result['error_details']['error_code'],
95+
$response,
96+
$result
97+
);
9298
}
9399

94100
return new ActivityDetails($receipt, $this->pemFile, $this->config->getLogger());

tests/Profile/ReceiptTest.php

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,21 @@ class ReceiptTest extends TestCase
3535
*/
3636
public $receipt;
3737

38+
/**
39+
* @throws \Yoti\Exception\PemFileException
40+
* @throws \Yoti\Exception\ReceiptException
41+
* @covers ::__construct
42+
*/
3843
public function setup(): void
3944
{
4045
$this->pemFile = PemFile::fromFilePath(TestData::PEM_FILE);
4146
$this->receiptArr = json_decode(file_get_contents(TestData::RECEIPT_JSON), true)['receipt'];
4247
$this->receipt = new Receipt($this->receiptArr);
4348
}
4449

45-
/**
46-
* @covers ::__construct
47-
* @covers ::validateReceipt
48-
*/
49-
public function testShouldThrowExceptionForInvalidReceipt()
50-
{
51-
$this->expectException(\Yoti\Exception\ReceiptException::class);
52-
53-
new Receipt([]);
54-
}
55-
5650
/**
5751
* @covers ::getTimestamp
52+
* @covers ::__construct
5853
*/
5954
public function testGetTimestamp()
6055
{

tests/Profile/ServiceTest.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use GuzzleHttp\Psr7;
88
use Psr\Http\Client\ClientInterface;
99
use Psr\Http\Message\ResponseInterface;
10+
use Yoti\Exception\ActivityDetailsException;
1011
use Yoti\Profile\ActivityDetails;
1112
use Yoti\Profile\Service;
1213
use Yoti\Test\TestCase;
@@ -160,8 +161,10 @@ public function testWrongPemFile()
160161
*/
161162
public function testSharingOutcomeFailure()
162163
{
164+
$mes1 = "Sharing activity unsuccessful for 9HNJDX5bEIN5TqBm0OGzVIc1LaAmbzfx6eIrwNdwpHvKeQmgPujyogC+r7hJCVPl ";
165+
$mes2 = "UNKNOWN FRAUD_DETECTED";
163166
$this->expectException(\Yoti\Exception\ActivityDetailsException::class);
164-
$this->expectExceptionMessage('Outcome was unsuccessful');
167+
$this->expectExceptionMessage($mes1 . $mes2);
165168

166169
$json = json_decode(file_get_contents(TestData::RECEIPT_JSON), true);
167170
$json['receipt']['sharing_outcome'] = 'FAILURE';
@@ -170,6 +173,27 @@ public function testSharingOutcomeFailure()
170173
$profileService->getActivityDetails(file_get_contents(TestData::YOTI_CONNECT_TOKEN));
171174
}
172175

176+
/**
177+
* @covers \Yoti\Exception\ActivityDetailsException::getReceiptErrorDetails
178+
* @covers \Yoti\Exception\ActivityDetailsException::__construct
179+
*/
180+
public function testReceiptErrorDetailsException()
181+
{
182+
$json = json_decode(file_get_contents(TestData::RECEIPT_JSON), true);
183+
$json['receipt']['sharing_outcome'] = 'FAILURE';
184+
185+
$profileService = $this->createProfileServiceWithResponse(200, json_encode($json));
186+
try {
187+
$profileService->getActivityDetails(file_get_contents(TestData::YOTI_CONNECT_TOKEN));
188+
} catch (ActivityDetailsException $e) {
189+
$this->assertEquals([
190+
'receipt_id' => '9HNJDX5bEIN5TqBm0OGzVIc1LaAmbzfx6eIrwNdwpHvKeQmgPujyogC+r7hJCVPl',
191+
'description' => 'UNKNOWN',
192+
'error_code' => 'FRAUD_DETECTED',
193+
], json_decode($e->getReceiptErrorDetails(), true));
194+
}
195+
}
196+
173197
/**
174198
* @covers ::getActivityDetails
175199
* @covers ::checkForReceipt

tests/sample-data/receipt.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,9 @@
1313
"parent_remember_me_id": "f5RjVQMyoKOvO/hkv43Ik+t6d6mGfP2tdrNijH4k4qafTG0FSNUgQIvd2Z3Nx1j8",
1414
"sharing_outcome": "SUCCESS",
1515
"timestamp": "2016-07-19T08:55:38Z"
16+
},
17+
"error_details": {
18+
"description": "UNKNOWN",
19+
"error_code" : "FRAUD_DETECTED"
1620
}
1721
}

0 commit comments

Comments
 (0)