Skip to content

Instantly share code, notes, and snippets.

@wilcorrea
Last active October 16, 2019 15:00
Show Gist options
  • Save wilcorrea/e2e66f05f30736a3e8db43bb780470e7 to your computer and use it in GitHub Desktop.
Save wilcorrea/e2e66f05f30736a3e8db43bb780470e7 to your computer and use it in GitHub Desktop.
<?php
namespace App\Http\Response;
use App\Http\Status;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Response;
/**
* Class Answer
* @package App\Http\Response
*/
abstract class Answer
{
/**
* @param mixed $data
* @param int $code
* @return JsonResponse
*/
public static function success($data, $code = Status::CODE_200)
{
$response = [
'status' => 'success',
'data' => $data,
];
return Response::json($response, $code);
}
/**
* @param mixed $data
* @param int $code
* @return JsonResponse
*/
public static function fail($data, $code = Status::CODE_400)
{
$response = [
'status' => 'fail',
'data' => $data,
];
return Response::json($response, $code);
}
/**
* @param string $message
* @param int $code
* @param mixed $data
* @param bool $commit
* @param bool $debug
* @return JsonResponse
*/
public static function error($message, $code = Status::CODE_500, $data = null, $commit = null, $debug = null)
{
$response = [
'commit' => $commit,
'status' => 'error',
'message' => $message,
];
if (!is_null($code)) {
$response['code'] = $code;
}
if (!is_null($data)) {
$response['data'] = $data;
}
if (!is_null($debug)) {
$response['$debug'] = $debug;
}
return Response::json($response, $code);
}
}
<?php
/**
* JSEND
* @link https://labs.omniti.com/labs/jsend
* |------------------------------------------------------------------------------------------------------------------|
* | Type | Description | Required Keys | Optional Keys |
* |------------------------------------------------------------------------------------------------------------------|
* | success | All went well, and (usually) some data was returned. | status, data | |
* |..........|.........................................................|........................|....................|
* | fail | There was a problem with the data submitted, or some | status, data | |
* | | pre-condition of the API call wasn't satisfied | | |
* |..........|.........................................................|........................|....................|
* | error | An error occurred in processing the request, i.e. an | status, message | code, data |
* | | exception was thrown | | |
* |------------------------------------------------------------------------------------------------------------------|
*/
namespace App\Http\Response;
use App\Http\Status;
use Illuminate\Http\JsonResponse;
/**
* Trait AnswerTrait
* @package App\Http\Response
*/
trait AnswerTrait
{
/**
* @param mixed $data
* @param int $code
* @return JsonResponse
*/
public function answerSuccess($data, $code = Status::CODE_200)
{
return Answer::success($data, $code);
}
/**
* @param mixed $data
* @param int $code
* @return JsonResponse
*/
public function answerFail($data, $code = Status::CODE_400)
{
return Answer::fail($data, $code);
}
/**
* @param string $message
* @param int $code
* @param mixed $data
* @param bool $commit
* @param bool $debug
* @return JsonResponse
*/
public function answerError($message, $code = Status::CODE_500, $data = null, $commit = null, $debug = null)
{
return Answer::error($message, $code, $data, $commit, $debug);
}
}
<?php
namespace App\Exceptions;
use App\Http\Status;
use Exception;
/**
* Class ErrorGeneral
* @package App\Exceptions
*/
abstract class ErrorGeneral extends Exception implements ErrorInterface
{
/**
* @var int
*/
protected $statusCode = Status::CODE_500;
/**
* @var array
*/
protected $details = [];
/**
* @var int
*/
protected $defaultMessage = 'Server error';
/**
* ErrorValidation constructor.
* @param array $details
* @param string|null $message
* @param int|null $code
* @param Exception|null $previous
*/
public function __construct(
array $details,
string $message = null,
?int $code = 0,
Exception $previous = null
) {
parent::__construct($message ? $message : $this->defaultMessage, $code, $previous);
$this->details = $details;
}
/**
* @return array
*/
public function getDetails(): array
{
return $this->details;
}
/**
* @return int
*/
public function getStatusCode(): int
{
return $this->statusCode;
}
}
<?php
namespace App\Exceptions;
/**
* Interface ErrorInterface
* @package App\Exceptions
*/
interface ErrorInterface
{
/**
* @return array
*/
public function getDetails(): array;
/**
* @return int
*/
public function getStatusCode(): int;
}
<?php
namespace App\Exceptions;
use App\Http\Response\AnswerTrait;
use App\Http\Status;
use Exception;
use ForceUTF8\Encoding;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response as IlluminateResponse;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
/**
* Class Handler
* @package App\Exceptions
*/
class Handler extends ExceptionHandler
{
/**
* @see AnswerTrait
*/
use AnswerTrait;
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param Exception $exception
* @return void
* @throws Exception
*/
public function report(Exception $exception)
{
if (app()->bound('sentry') && $this->shouldReport($exception)) {
app('sentry')->captureException($exception);
}
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param Request $request
* @param Exception $exception
* @return JsonResponse|IlluminateResponse|SymfonyResponse
*/
public function render($request, Exception $exception)
{
$route = $request->route();
if (!$route || in_array('api', $route->middleware())) {
$request->headers->set('Accept', 'application/json');
}
if ($exception instanceof ErrorGeneral) {
return $this->answerWith($exception);
}
if ($exception instanceof UnauthorizedHttpException) {
$message = 'Unauthorized';
$data = [];
if ($exception->getMessage() === 'Token has expired') {
$data['token'] = 'expired';
}
return $this->answerError($message, Status::CODE_401, $data);
}
if ($exception instanceof QueryException) {
$bindings = $exception->getBindings();
if (!is_array($bindings)) {
$bindings = [$bindings];
}
foreach ($bindings as $key => $binding) {
$bindings[$key] = Encoding::fixUTF8($binding);
}
$message = Encoding::fixUTF8($exception->getMessage());
$data = [
'sql' => $exception->getSql(),
'bindings' => $bindings,
];
return $this->answerError($message, Status::CODE_500, $data);
}
return parent::render($request, $exception);
}
/**
* @param ErrorGeneral $exception
* @return JsonResponse
*/
protected function answerWith(ErrorGeneral $exception)
{
$code = $exception->getStatusCode();
$data = $exception->getDetails();
if ($code >= 400 && $code < 500) {
return $this->answerFail($data, $code);
}
$message = $exception->getMessage();
$debug = '';
if (env('APP_DEBUG')) {
$debug = utf8_encode($exception->getTraceAsString());
}
return $this->answerError($message, $code, $data, false, $debug);
}
}
<?php
namespace App\Http;
/**
* Class Status
* @package App\Http
*/
class Status
{
/**
* Continue
* @var integer
*/
const CODE_100 = 100;
/**
* Switching Protocols
* @var integer
*/
const CODE_101 = 101;
/**
* Processing
* @var integer
*/
const CODE_102 = 102;
/**
* Early Hints
* @var integer
*/
const CODE_103 = 103;
/**
* OK
* @var integer
*/
const CODE_200 = 200;
/**
* Created
* @var integer
*/
const CODE_201 = 201;
/**
* Accepted
* @var integer
*/
const CODE_202 = 202;
/**
* Non-Authoritative Information
* @var integer
*/
const CODE_203 = 203;
/**
* No Content
* @var integer
*/
const CODE_204 = 204;
/**
* Reset Content
* @var integer
*/
const CODE_205 = 205;
/**
* Partial Content
* @var integer
*/
const CODE_206 = 206;
/**
* Multi-Status
* @var integer
*/
const CODE_207 = 207;
/**
* Already Reported
* @var integer
*/
const CODE_208 = 208;
/**
* IM Used
* @var integer
*/
const CODE_226 = 226;
/**
* Multiple Choices
* @var integer
*/
const CODE_300 = 300;
/**
* Moved Permanently
* @var integer
*/
const CODE_301 = 301;
/**
* Found
* @var integer
*/
const CODE_302 = 302;
/**
* See Other
* @var integer
*/
const CODE_303 = 303;
/**
* Not Modified
* @var integer
*/
const CODE_304 = 304;
/**
* Use Proxy
* @var integer
*/
const CODE_305 = 305;
/**
* Temporary Redirect
* @var integer
*/
const CODE_307 = 307;
/**
* Permanent Redirect
* @var integer
*/
const CODE_308 = 308;
/**
* Bad Request
* @var integer
*/
const CODE_400 = 400;
/**
* Unauthorized
* @var integer
*/
const CODE_401 = 401;
/**
* Payment Required
* @var integer
*/
const CODE_402 = 402;
/**
* Forbidden
* @var integer
*/
const CODE_403 = 403;
/**
* Not Found
* @var integer
*/
const CODE_404 = 404;
/**
* Method Not Allowed
* @var integer
*/
const CODE_405 = 405;
/**
* Not Acceptable
* @var integer
*/
const CODE_406 = 406;
/**
* Proxy Authentication Required
* @var integer
*/
const CODE_407 = 407;
/**
* Request Timeout
* @var integer
*/
const CODE_408 = 408;
/**
* Conflict
* @var integer
*/
const CODE_409 = 409;
/**
* Gone
* @var integer
*/
const CODE_410 = 410;
/**
* Length Required
* @var integer
*/
const CODE_411 = 411;
/**
* Precondition Failed
* @var integer
*/
const CODE_412 = 412;
/**
* Payload Too Large
* @var integer
*/
const CODE_413 = 413;
/**
* URI Too Long
* @var integer
*/
const CODE_414 = 414;
/**
* Unsupported Media Type
* @var integer
*/
const CODE_415 = 415;
/**
* Range Not Satisfiable
* @var integer
*/
const CODE_416 = 416;
/**
* Expectation Failed
* @var integer
*/
const CODE_417 = 417;
/**
* I\'m a teapot
* @var integer
*/
const CODE_418 = 418;
/**
* Misdirected Request
* @var integer
*/
const CODE_421 = 421;
/**
* Unprocessable Entity
* @var integer
*/
const CODE_422 = 422;
/**
* Locked
* @var integer
*/
const CODE_423 = 423;
/**
* Failed Dependency
* @var integer
*/
const CODE_424 = 424;
/**
* Too Early
* @var integer
*/
const CODE_425 = 425;
/**
* Upgrade Required
* @var integer
*/
const CODE_426 = 426;
/**
* Precondition Required
* @var integer
*/
const CODE_428 = 428;
/**
* Too Many Requests
* @var integer
*/
const CODE_429 = 429;
/**
* Request Header Fields Too Large
* @var integer
*/
const CODE_431 = 431;
/**
* Unavailable For Legal Reasons
* @var integer
*/
const CODE_451 = 451;
/**
* Internal Server Error
* @var integer
*/
const CODE_500 = 500;
/**
* Not Implemented
* @var integer
*/
const CODE_501 = 501;
/**
* Bad Gateway
* @var integer
*/
const CODE_502 = 502;
/**
* Service Unavailable
* @var integer
*/
const CODE_503 = 503;
/**
* Gateway Timeout
* @var integer
*/
const CODE_504 = 504;
/**
* HTTP Version Not Supported
* @var integer
*/
const CODE_505 = 505;
/**
* Variant Also Negotiates
* @var integer
*/
const CODE_506 = 506;
/**
* Insufficient Storage
* @var integer
*/
const CODE_507 = 507;
/**
* Loop Detected
* @var integer
*/
const CODE_508 = 508;
/**
* Not Extended
* @var integer
*/
const CODE_510 = 510;
/**
* Network Authentication Required
* @var integer
*/
const CODE_511 = 511;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment