1<?php
2/*
3 * This file is part of PHPUnit.
4 *
5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11/**
12 * Wraps Exceptions thrown by code under test.
13 *
14 * Re-instantiates Exceptions thrown by user-space code to retain their original
15 * class names, properties, and stack traces (but without arguments).
16 *
17 * Unlike PHPUnit_Framework_Exception, the complete stack of previous Exceptions
18 * is processed.
19 */
20class PHPUnit_Framework_ExceptionWrapper extends PHPUnit_Framework_Exception
21{
22    /**
23     * @var string
24     */
25    protected $className;
26
27    /**
28     * @var PHPUnit_Framework_ExceptionWrapper|null
29     */
30    protected $previous;
31
32    /**
33     * @param Throwable|Exception $e
34     */
35    public function __construct($e)
36    {
37        // PDOException::getCode() is a string.
38        // @see http://php.net/manual/en/class.pdoexception.php#95812
39        parent::__construct($e->getMessage(), (int) $e->getCode());
40
41        $this->className = get_class($e);
42        $this->file      = $e->getFile();
43        $this->line      = $e->getLine();
44
45        $this->serializableTrace = $e->getTrace();
46
47        foreach ($this->serializableTrace as $i => $call) {
48            unset($this->serializableTrace[$i]['args']);
49        }
50
51        if ($e->getPrevious()) {
52            $this->previous = new self($e->getPrevious());
53        }
54    }
55
56    /**
57     * @return string
58     */
59    public function getClassName()
60    {
61        return $this->className;
62    }
63
64    /**
65     * @return PHPUnit_Framework_ExceptionWrapper
66     */
67    public function getPreviousWrapped()
68    {
69        return $this->previous;
70    }
71
72    /**
73     * @return string
74     */
75    public function __toString()
76    {
77        $string = PHPUnit_Framework_TestFailure::exceptionToString($this);
78
79        if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) {
80            $string .= "\n" . $trace;
81        }
82
83        if ($this->previous) {
84            $string .= "\nCaused by\n" . $this->previous;
85        }
86
87        return $string;
88    }
89}
90