Skip to content

Commit

Permalink
Merge pull request #4 from telebugs/guzzle
Browse files Browse the repository at this point in the history
Make it possible to send exceptions
  • Loading branch information
kyrylo authored Jun 26, 2024
2 parents 1432e51 + 7bea7f7 commit 0307655
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 7 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
}
],
"require": {
"php": ">=8.1"
"php": ">=8.1",
"guzzlehttp/guzzle": "^7.8"
},
"require-dev": {
"phpunit/phpunit": "^10.5"
Expand Down
16 changes: 16 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class Config
{
private const ERROR_API_URL = "https://api.telebugs.com/2024-03-28/errors";

private $httpClient;

private $apiKey;
private $apiURL;
private $rootDirectory;
Expand All @@ -27,11 +29,22 @@ public function __construct()

public function reset(): void
{
$this->httpClient = null;
$this->apiKey = null;
$this->apiURL = self::ERROR_API_URL;
$this->rootDirectory = "";
}

public function setHttpClient($httpClient): void
{
$this->httpClient = $httpClient;
}

public function getHttpClient()
{
return $this->httpClient;
}

public function getApiKey(): ?string
{
return $this->apiKey;
Expand Down Expand Up @@ -64,6 +77,9 @@ public function setRootDirectory(string $rootDirectory): void

public function configure(array $options): void
{
if (isset($options['http_client'])) {
$this->setHttpClient($options['http_client']);
}
if (isset($options['api_key'])) {
$this->setApiKey($options['api_key']);
}
Expand Down
35 changes: 35 additions & 0 deletions src/Promise.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Telebugs;

use GuzzleHttp\Promise\PromiseInterface;

class Promise
{
private $promise;

public function __construct(PromiseInterface $promise)
{
$this->promise = $promise;
}

public function then(...$args): Promise
{
return new Promise($this->promise->then(...$args));
}

public function otherwise(...$args): Promise
{
return new Promise($this->promise->otherwise(...$args));
}

public function wait(...$args): mixed
{
return $this->promise->wait(...$args);
}

public function getState(): string
{
return $this->promise->getState();
}
}
29 changes: 27 additions & 2 deletions src/Reporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

namespace Telebugs;

use Telebugs\Promise;

class Reporter
{
public const VERSION = '0.1.0';

private static $instance;

public static function getInstance(): Reporter
Expand All @@ -14,8 +18,29 @@ public static function getInstance(): Reporter
return self::$instance;
}

public function report(\Throwable $e): void
private $sender;

public function __construct()
{
$this->sender = new Sender();
}

public function report(\Throwable $e): Promise
{
$className = get_class($e);
return $this->sender->send(json_encode([
'errors' => [
[
'type' => get_class($e),
'message' => $e->getMessage(),
'backtrace' => [
[
'file' => $e->getFile(),
'line' => $e->getLine(),
'function' => 'funcName'
]
],
]
]
]));
}
}
51 changes: 51 additions & 0 deletions src/Sender.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Telebugs;

use GuzzleHttp;

use Telebugs\Promise;

use Psr\Http\Message\ResponseInterface;

class Sender
{
private const CONTENT_TYPE = 'application/json';

private const USER_AGENT = 'telebugs-php/' . Reporter::VERSION . ' (php/' . PHP_VERSION . ')';

private $config;

private $client;
private $authorization;

public function __construct()
{
$this->config = Config::getInstance();

if ($this->config->getHttpClient() !== null) {
$this->client = $this->config->getHttpClient();
} else {
$this->client = new GuzzleHttp\Client();
}

$this->authorization = 'Bearer ' . $this->config->getApiKey();
}

public function send(string $data): Promise
{
$guzzlePromise = $this->client->postAsync($this->config->getApiURL(), [
'body' => $data,
'headers' => [
'Content-Type' => self::CONTENT_TYPE,
'User-Agent' => self::USER_AGENT,
'Authorization' => $this->authorization
]
]);

$promise = new Promise($guzzlePromise);
return $promise->then(function (ResponseInterface $res) {
return json_decode($res->getBody()->getContents(), true);
});
}
}
5 changes: 3 additions & 2 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

use Telebugs\Config;
use Telebugs\Reporter;
use Telebugs\Promise;

function configure(array $options = []): void
{
Config::getInstance()->configure($options);
}

function report(\Throwable $e): void
function report(\Throwable $e): Promise
{
Reporter::getInstance()->report($e);
return Reporter::getInstance()->report($e);
}
6 changes: 6 additions & 0 deletions tests/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ public function testConfigure()
$this->assertEquals("/var/www/html", self::$config->getRootDirectory());
}

public function testSetHttpClient()
{
self::$config->setHttpClient(new \GuzzleHttp\Client());
$this->assertInstanceOf(\GuzzleHttp\Client::class, self::$config->getHttpClient());
}

public function testReset()
{
self::$config->reset();
Expand Down
27 changes: 27 additions & 0 deletions tests/FunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,44 @@
namespace Telebugs\Tests;

use PHPUnit\Framework\TestCase;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Client;

use Telebugs\Config;

use function Telebugs\configure;
use function Telebugs\report;

class FunctionsTest extends TestCase
{
protected function tearDown(): void
{
Config::getInstance()->reset();
}

public function testConfigure(): void
{
configure(['api_key' => "999"]);

$this->assertEquals("999", Config::getInstance()->getApiKey());
}

public function testReport(): void
{
$mock = new MockHandler([
new Response(201, [], '{"id":123}'),
]);
$handlerStack = HandlerStack::create($mock);

configure([
'api_key' => "1:a0480999c3d12d13d4cdbadbf0fc2ba3",
'http_client' => new Client(['handler' => $handlerStack]),
]);

$res = report(new \Exception("Test exception"))->wait();

$this->assertEquals(123, $res['id']);
}
}
44 changes: 44 additions & 0 deletions tests/PromiseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Telebugs\Tests;

use PHPUnit\Framework\TestCase;

use Telebugs\Promise;

class PromiseTest extends TestCase
{
public function testThen(): void
{
$promise = new Promise(new \GuzzleHttp\Promise\FulfilledPromise(1));
$newPromise = $promise->then(function ($value) {
return $value + 1;
});

$this->assertEquals(2, $newPromise->wait());
}

public function testOtherwise(): void
{
$promise = new Promise(new \GuzzleHttp\Promise\RejectedPromise(1));
$newPromise = $promise->otherwise(function ($value) {
return $value + 1;
});

$this->assertEquals(2, $newPromise->wait());
}

public function testWait(): void
{
$promise = new Promise(new \GuzzleHttp\Promise\FulfilledPromise(1));

$this->assertEquals(1, $promise->wait());
}

public function testGetState(): void
{
$promise = new Promise(new \GuzzleHttp\Promise\FulfilledPromise(1));

$this->assertEquals("fulfilled", $promise->getState());
}
}
28 changes: 26 additions & 2 deletions tests/ReporterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,36 @@
use PHPUnit\Framework\TestCase;

use Telebugs\Reporter;
use Telebugs\Config;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Client;

use function Telebugs\configure;

class ReporterTest extends TestCase
{
protected function tearDown(): void
{
Config::getInstance()->reset();
}

public function testReport()
{
$reporter = Reporter::getInstance();
$this->assertInstanceOf(Reporter::class, $reporter);
$mock = new MockHandler([
new Response(201, [], '{"id":123}'),
]);
$handlerStack = HandlerStack::create($mock);

configure([
'api_key' => "1:a0480999c3d12d13d4cdbadbf0fc2ba3",
'http_client' => new Client(['handler' => $handlerStack]),
]);

$reporter = new Reporter();
$res = $reporter->report(new \Exception("Test exception"))->wait();

$this->assertEquals(123, $res['id']);
}
}

0 comments on commit 0307655

Please sign in to comment.