FuelPHPのエラー処理の雑多メモ

2013-03-10T00:00:00+00:00 FuelPHP PHP

久々にFuelPHPを使ってて思う所がいろいろあったのでメモ

まずFuelPHPのhttpexceptions.php。PHPの例外クラスが定義されていて、それで且つresponseメソッドを使う事でエラービューなどを表示したりなどの事が出来ている訳なんだが。個人的には例外出しても良いんだろうけど、前にも書いたがFuel\CoreRequestとかを使ってテストを書いたりする際には例外ではなくHttpNotFoundExceptionであれば404、HttpServerErrorExceptionであれば500を取得できるようにしてテストしたいって思う所があるんだけど。で思ったのが「throw new HttpNotFoundException」ではなく「return new HttpNotFoundException」をしつつafterでそれを処理するっていうのはどうだろうと。という事で色々やってみた

<?php

class Controller_Home extends Controller_Rest {

    protected $_supported_formats = array(
        "html" => "text/html",
        "json" => "application/json"
    );

    public function get_index() {
        if ($this->format === "html") {
            return new HttpServerErrorException();
        }

        return $this->response(array("message" => "hoge fuga foobar"));
    }

    public function after($res) {
        if ($res instanceof HttpException) {
            $res = $res->response();
        }

        // 上記処理後でもResponseじゃない場合はHttpServerErrorExceptionをスローさせる

        if (!($res instanceof Response)) {
            throw new HttpServerErrorException();
        }

        return parent::after($res);
    }
}

でこれをテストする場合

<?php

class SampleTestCase extends PHPUnit_Framework_TestCase {

    private $pid;

    public function setUp() {
        $this->pid = pcntl_fork();
    }

    public function tearDown() {
        posix_kill($this->pid, SIGINT);
    }

    public function test1() {
        if ($this->pid == 0) {
            pcntl_exec(
                "/home/kinjouj/.phpbrew/php/php-5.4.12/bin/php",
                ["-S", "localhost:8080", "-t", DOCROOT."/public"]
            );
        } elseif($this->pid) {
            sleep(1);

            $driver = Request::forge("http://localhost:8080", "Curl");
            //$driver->set_mime_type("json");

            $res = $driver->execute()->response();
            $this->assertThat($res->status, $this->equalTo(200));
            $this->assertThat(
                $res->body,
                $this->equalTo(array("message" => "hoge fuga foobar"))
            );
        }
    }
}

とするとどうなるか。まだ例外が出る。理由としてfuel/core/classes/request/curl.php(178行目辺り)では

elseif ($this->response->status >= 400) {
    throw new RequestStatusException($body, $this->response->status);

    // スローしない場合は普通に$thisを返せばエラーでもレスポンス(404とか500)を取るのは可能
}

というような処理が行われて結局例外を出さずともこっちで例外にしちゃってる訳。マジうざいんだけどっていうギャルJKっぽい発言が飛び出しちゃう訳で。とりあえずそこな所のコードもろもろ消しちゃう(やった場合にテストするべきかと)

でテストを実行

Tests Running...This may take a few moments.
[Thu Mar  7 18:09:44 2013] 127.0.0.1:46269 [500]: /
PHP 5.4.12 Development Server started at Thu Mar  7 18:09:43 2013
Listening on http://localhost:8080
Document root is /home/kinjouj/Desktop/sample/public
Press Ctrl-C to quit.
PHPUnit 3.7.15 by Sebastian Bergmann.

Configuration read from /home/kinjouj/Desktop/sample/fuel/core/phpunit.xml

F

Time: 0 seconds, Memory: 3.00Mb

There was 1 failure:

1) SampleTestCase::test1
Failed asserting that 500 matches expected 200.

/home/kinjouj/Desktop/sample/fuel/app/tests/controller/test1.php:27

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

っていう感じになる訳だ。まぁテストコケるようになってるので(コメントしている所が)

てな感じかなーっと。なんつーかなんでもかんでも例外出しちゃってそれを「PHPUnitのsetExpectedException的なのを処理すればオッケーよ」みたいなのはこういうケースだとどうなのかなーって思う所

crxmakeを使ってChrome Extensionをビルド Backgridを試してみる