Skip to content

Commit c0ba41e

Browse files
author
Paul
committed
Polished TryCatch tests and documentation.
1 parent 6d21f83 commit c0ba41e

File tree

4 files changed

+69
-40
lines changed

4 files changed

+69
-40
lines changed

README.md

+15-13
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ The following strategies ship with Mapper and provide a suite of commonly used f
294294
- [Merge](#merge) – Merges two data sets together giving precedence to the latter if keys collide.
295295
- [TakeFirst](#takefirst) – Takes the first value from a collection one or more times.
296296
- [ToList](#tolist) – Converts data to a single-element list unless it is already a list.
297+
- [TryCatch](#trycatch) – Tries the primary strategy and falls back to an expression if an exception is thrown.
297298
- [Type](#type) – Casts data to the specified type.
298299
- [Unique](#unique) – Creates a collection of unique values by removing duplicates.
299300
- [Walk](#walk) – Walks a nested structure to the specified element in the same manner as `Copy`.
@@ -652,41 +653,42 @@ ToList(Strategy|Mapping|array|mixed $expression)
652653
653654
### TryCatch
654655

655-
Uses the handler callback to catch and manage any exception thrown by the primary strategy, if an exception was raised delegates to a fallback expression.
656+
Tries the primary strategy and falls back to an expression if an exception is thrown. The thrown exception is passed to the specified exception handler. The handler should throw an exception if it does not expect the exception type it receives.
656657

657-
It is possible to use nested TryCatch strategies to manage different types of exceptions.
658+
Different fallback expressions can be used for different exception types by nesting multiple instances of this strategy.
658659

659660
#### Signature
660661

661662
```php
662663
TryCatch(Strategy $strategy, callable $handler, Strategy|Mapping|array|mixed $expression)
663664
```
664665

665-
1. `$strategy` – Primary Strategy that might raise an exception.
666-
2. `$handler` – Handler function that receives the raised exception as its first argument.
667-
1. `$expression` – Expression.
666+
1. `$strategy` – Primary strategy.
667+
2. `$handler` – Exception handler that receives the thrown exception as its first argument.
668+
3. `$expression` – Fallback expression.
668669

669670
#### Examples
670671

671672
```php
672673
(new Mapper)->map(
673-
[],
674+
['foo' => 'bar'],
674675
new TryCatch(
675676
new Callback(
676-
function ($data, $context) {
677-
throw new \LogicException;
677+
function () {
678+
throw new \DomainException;
678679
}
679680
),
680-
function (\Exception $e) {
681-
if (! $e instanceof \LogicException) {
682-
throw $e;
681+
function (\Exception $exception) {
682+
if (!$exception instanceof \DomainException) {
683+
throw $exception;
683684
}
684685
},
685-
'LogicExceptionHandled'
686+
new Copy('foo')
686687
)
687688
);
688689
```
689-
> 'LogicExceptionHandled'
690+
691+
> 'bar'
690692
691693
### Type
692694

src/Strategy/TryCatch.php

+10-8
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@
44
use ScriptFUSION\Mapper\Mapping;
55

66
/**
7-
* TryCatch uses the handler callback to catch and manage any exception thrown by
8-
* the primary strategy, if an exception was raised delegates to a fallback expression.
7+
* Tries the primary strategy and falls back to an expression if an exception is thrown.
98
*/
109
class TryCatch extends Decorator
1110
{
12-
private $expression;
11+
/** @var callable */
1312
private $handler;
1413

14+
/** @var Strategy|Mapping|array|mixed */
15+
private $expression;
16+
1517
/**
16-
* @param Strategy $strategy
17-
* @param callable $handler
18-
* @param Strategy|Mapping|array|mixed $expression
18+
* @param Strategy $strategy Primary strategy.
19+
* @param callable $handler Exception handler.
20+
* @param Strategy|Mapping|array|mixed $expression Fallback expression.
1921
*/
2022
public function __construct(Strategy $strategy, callable $handler, $expression)
2123
{
@@ -29,8 +31,8 @@ public function __invoke($data, $context = null)
2931
{
3032
try {
3133
return parent::__invoke($data, $context);
32-
} catch (\Exception $e) {
33-
call_user_func($this->handler, $e);
34+
} catch (\Exception $exception) {
35+
call_user_func($this->handler, $exception);
3436

3537
return $this->delegate($this->expression, $data, $context);
3638
}

test/Functional/DocumentationTest.php

+24
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use ScriptFUSION\Mapper\Strategy\Merge;
1616
use ScriptFUSION\Mapper\Strategy\TakeFirst;
1717
use ScriptFUSION\Mapper\Strategy\ToList;
18+
use ScriptFUSION\Mapper\Strategy\TryCatch;
1819
use ScriptFUSION\Mapper\Strategy\Type;
1920
use ScriptFUSION\Mapper\Strategy\Unique;
2021
use ScriptFUSION\Mapper\Strategy\Walk;
@@ -247,6 +248,29 @@ public function testToList()
247248
);
248249
}
249250

251+
public function testTryCatch()
252+
{
253+
self::assertSame(
254+
'bar',
255+
(new Mapper)->map(
256+
['foo' => 'bar'],
257+
new TryCatch(
258+
new Callback(
259+
function () {
260+
throw new \DomainException;
261+
}
262+
),
263+
function (\Exception $exception) {
264+
if (!$exception instanceof \DomainException) {
265+
throw $exception;
266+
}
267+
},
268+
new Copy('foo')
269+
)
270+
)
271+
);
272+
}
273+
250274
public function testType()
251275
{
252276
self::assertSame(

test/Integration/Mapper/Strategy/TryCatchTest.php

+20-19
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ final class TryCatchTest extends \PHPUnit_Framework_TestCase
1212
protected function setUp()
1313
{
1414
$this->callback = new Callback(function ($data) {
15-
if ($data[0] === 'LogicError') {
16-
throw new \LogicException('Test Logic Exception');
17-
}
18-
if ($data[0] === 'DomainError') {
19-
throw new \DomainException('Test Domain Exception');
15+
if ($data[0] instanceof \Exception) {
16+
throw $data[0];
2017
}
2118

2219
return $data;
@@ -30,45 +27,49 @@ public function testTryCatch()
3027
new TryCatch(
3128
$this->callback,
3229
function (\Exception $e) {
33-
if (! $e instanceof \DomainException) {
30+
if (!$e instanceof \DomainException) {
3431
throw $e;
3532
}
3633
},
37-
'ExceptionHandled'
34+
$fallback = 'bar'
3835
)
3936
)->setMapper(new Mapper);
4037

41-
self::assertSame(['foo', 'bar'], $tryCatch(['foo', 'bar']));
42-
self::assertSame('ExceptionHandled', $tryCatch(['DomainError', 'foo']));
43-
$this->setExpectedException(\LogicException::class);
44-
self::assertNotEquals('ExceptionHandled', $tryCatch(['LogicError', 'foo']));
38+
self::assertSame($data = ['foo'], $tryCatch($data));
39+
self::assertSame($fallback, $tryCatch([new \DomainException]));
40+
41+
$this->setExpectedException(\RuntimeException::class);
42+
$tryCatch([new \RuntimeException]);
4543
}
4644

47-
public function testMultipleTryCatch()
45+
public function testNestedTryCatch()
4846
{
4947
/** @var TryCatch $tryCatch */
5048
$tryCatch = (
5149
new TryCatch(
5250
new TryCatch(
5351
$this->callback,
5452
function (\Exception $e) {
55-
if (! $e instanceof \DomainException) {
53+
if (!$e instanceof \DomainException) {
5654
throw $e;
5755
}
5856
},
59-
'DomainExceptionHandled'
57+
$innerFallback = 'bar'
6058
),
6159
function (\Exception $e) {
62-
if (! $e instanceof \LogicException) {
60+
if (!$e instanceof \LogicException) {
6361
throw $e;
6462
}
6563
},
66-
'LogicExceptionHandled'
64+
$outerFallback = 'baz'
6765
)
6866
)->setMapper(new Mapper);
6967

70-
self::assertSame(['foo', 'bar'], $tryCatch(['foo', 'bar']));
71-
self::assertSame('LogicExceptionHandled', $tryCatch(['LogicError', 'foo']));
72-
self::assertSame('DomainExceptionHandled', $tryCatch(['DomainError', 'foo']));
68+
self::assertSame($data = ['foo'], $tryCatch($data));
69+
self::assertSame($innerFallback, $tryCatch([new \DomainException]));
70+
self::assertSame($outerFallback, $tryCatch([new \LogicException]));
71+
72+
$this->setExpectedException(\RuntimeException::class);
73+
$tryCatch([new \RuntimeException]);
7374
}
7475
}

0 commit comments

Comments
 (0)