I just Implement Slack for logs in Laravel as follow:
in logging.php
'default' => env('LOG_CHANNEL', 'slack'),
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL', 'https://hooks.slack.com/services/xxxx/xx'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => env('LOG_LEVEL', 'critical'),
],
In Handler.php I just add:
public function report(Throwable $exception)
{
Log::channel('slack')->critical($exception);
}
whenever I visit any route link in my app I got this error in slack!
Symfony\Component\HttpKernel\Exception\NotFoundHttpException in /Users/Ali/Documents/Sites/asu-admin/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php:43
Stack trace:
#0 /Users/Ali/Documents/Sites/asu-admin/vendor/laravel/framework/src/Illuminate/Routing/CompiledRouteCollection.php(144): Illuminate\Routing\AbstractRouteCollection->handleMatchedRoute(Object(Illuminate\Http\Request), NULL)
#1 /Users/Ali/Documents/Sites/asu-admin/vendor/laravel/framework/src/Illuminate/Routing/Router.php(647): Illuminate\Routing\CompiledRouteCollection->match(Object(Illuminate\Http\Request))
#2 /Users/Ali/Documents/Sites/asu-admin/vendor/laravel/framework/src/Illuminate/Routing/Router.php(636): Illuminate\Routing\Router->findRoute(Object(Illuminate\Http\Request))
I just clear route clear and route:cache and everything related but still, every visit to any route this exception pushed to slack!
The reality of the matter is those exceptions were probably always there. Here's an excerpt of the built-in error handler of Laravel:
protected $internalDontReport = [
AuthenticationException::class,
AuthorizationException::class,
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
MultipleRecordsFoundException::class,
RecordsNotFoundException::class,
SuspiciousOperationException::class,
TokenMismatchException::class,
ValidationException::class,
];
and this is used in
protected function shouldntReport(Throwable $e)
{
$dontReport = array_merge($this->dontReport, $this->internalDontReport);
return ! is_null(Arr::first($dontReport, function ($type) use ($e) {
return $e instanceof $type;
}));
}
therefore in order for you to properly report exceptions the same way you need to do something like:
public function report(Throwable $exception)
{
if ($this->shoudntReport($exception) { return; }
Log::channel('slack')->critical($exception);
}
As a sidenote 404 exceptions happen all the time. When I load a page the browser will often try different things out like loading a favicon or a page manifest.json of finding the search.xml and various things like this sometimes because we add the metadata in our template and then forget to add the actual files and other times because the browser tries to be "smart" about it.
If you want to eliminate these exceptions you need to first figure out which page is not found. It probably isn't the route action itself otherwise you'd know from the response.
Related
Instead of showing an error page I'd like to redirect the user to the start page in general, if the route is invalid (there is no controller/action like requested). To make it sound the redirection should only happen on 'normal' page requests. Though AJAX calls can be invalid as well, I don't want to send a redirect to the browser here.
How can I do this efficiently?
You can override ErrorAction class and will implement necessary logic. For example:
class MyErrorAction extends \yii\web\ErrorAction
{
public $redirectRoute;
public function run()
{
if (!Yii::$app->getRequest()->getIsAjax()) {
Yii::$app->getResponse()->redirect($this->redirectRoute)->send();
return;
}
return parent::run();
}
}
After it, you should add this action in a controller and configure it
class SiteController
{
public function actions()
{
return [
'error' => [
'class' => MyErrorAction::class
'redirectRoute' => 'site/my-page'
],
];
}
}
and configure the route of error action in the error handler
'errorHandler' => [
'errorAction' => 'site/error',
]
I used Laravel Cashier to handle my user's subscription, however when I try to do the basic cancellation $user->subscription('main')->cancel(), an exception is being thrown
BadMethodCallException: Call to undefined method Illuminate\Database\Query\Builder::asStripeCustomer() in
\try\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2483
Stack trace:
\try\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php(1470): Illuminate\Database\Eloquent\Builder->__call('asStripeCustome...', Array)
\try\vendor\laravel\cashier\src\Subscription.php(345): Illuminate\Database\Eloquent\Model->__call('asStripeCustome...', Array)
\try\vendor\laravel\cashier\src\Subscription.php(256): Laravel\Cashier\Subscription->asStripeSubscription()
I setup the Model correctly and I uses the Billable trait so I really have no idea what's really causing this error
App\User.php
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Cashier\Billable;
class User extends Authenticatable{
use Billable;
...
}
App\Http\Controllers\UserController.php
public function cancelSubscription(Request $request)
{
$user = $request->user();
try {
if ($user->subscription('main')->onTrial()) {
$user->subscription('main')->cancelNow();
} else {
$user->subscription('main')->cancel();
}
} catch (\Exception $e) {
\Log::error($e);
return [
'success' => 0,
'message' => "Something went wrong while trying cancel your subscription. Please try again later."
];
}
Any help and hints will be greatly appreciated, thanks in advance!
My bad, I just found out that it was actually with my stripe configuration on /config/services.php as I have two models for my Users (because I'm also using another package other than laravel-cashier to handle payments via Authorize.net on which I ended up creating different Models for them to work)
'stripe' => [
// 'model' => App\AnetUser::class, => this actually caused the error as
// ->asStripeCustomer() doesn't exists on an Authorize.net's Billable trait
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
I feel so stupid. XD
Hi I've never worked with Laravel Cashier before but, I think the root of your problem might be that you are accessing user from the request, therefore it's not a user instance thats why it triggers undefined methods errors.
So creating a user instance should probably work out for you:
Note: I don't know if $request->user is primary key or whole user instance so I added different solutions
public function cancelSubscription(Request $request)
{
// if $request->user is the user instance you can do this:
$user = App\User::findOrFail($request->user->id);
// if $request->user was any other field from user you could retrieve
// the user using something like->
// App\User::where('fieldName', 'LIKE', $request->user)->firstOrFail();
try {
if ($user->subscription('main')->onTrial()) {
$user->subscription('main')->cancelNow();
} else {
$user->subscription('main')->cancel();
}
} catch (\Exception $e) {
\Log::error($e);
return [
'success' => 0,
'message' => "Something went wrong while trying cancel your subscription. Please try again later."
];
}
}
PHP offers the possibility to set customer error handlers with set_error_handler("customError",E_USER_WARNING); (for example).
How and where can I set some default error handlers for a Symfony 4 application to make sure I catch all unhandled errors?
I have noticed the Debug component which mentions ErrorHandler::register();. Is this the safety net I am looking for? If yes, where should I put that error handler registration call in my code? Should I modify the index.php page?
Do the kernel events may be a solution to your issue ?
http://symfony.com/doc/current/event_dispatcher.html
You can check out all requests made on your kernel or controllers and even stop propagation of them.
In your index.php, you can use it like below:
$app->error(function (\Exception $e, $code) use ($app) {
$errors = [
[
'status' => $code,
'detail' => $e->getMessage()
]
];
if ($app['debug'] === true) {
$errors['file'] = $e->getFile();
$errors['line'] = $e->getLine();
}
return new JsonResponse(['errors' => $errors]);
});
I have used the Laravel Auditing plugin (http://www.laravel-auditing.com/docs/3.1) to log the all models changes.Am using different auth system but the Laravel Auditing
getLoggedInUserId()
using laravel core one so need to change that. i have forked this plugin and edited the function directly its worked. But i like to find another ways if you have idea share with me ?
protected function getLoggedInUserId()
{
try {
if (Auth::check()) {
return Auth::user()->getAuthIdentifier();
}
} catch (\Exception $e) {
return;
}
}
Unfortunately, until version 4 of the package, you couldn't change the user resolver without modifying the actual code.
However, from version 4 onwards, you can do so in the configuration file (config/audit.php).
The user resolver can be set in two ways.
As a Closure:
return [
'user' = [
'resolver' => function () {
return Auth::check() ? Auth::user()->getAuthIdentifier() : null;
},
],
];
As a FQCN:
return [
'user' = [
'resolver' => App\User::class,
],
];
TIP: You have to implement the OwenIt\Auditing\Contracts\UserResolver interface in the App\User class for this to work.
See the full documentation here.
I've been struggling with this for a while now.
Here's the code I've got.
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|max:100'
]);
if ($validator->fails()) {
//do something
}
}
The problem is that I get a FatalThrowableError right in my face with the following message:
Call to a member function parameter() on array
I can't find what I'm doing wrong. I'd appreciate some help here.
And also, I've had this validation before which worked:
$this->validate($request, [
'name' => 'required|unique:developers|max:100'
]);
But the thing with this one is, I had no idea how to catch when the validation failed. Is it possible to catch the validation fail when using it this way?
Using version: "laravel/lumen-framework": "5.2.*"
A FatalThrowableError exception is low level exception that is thrown typically by the symfony debug ErrorHandler. In lumen the queue worker, PhpEngine, console kernel and routing pipeline uses it as well.
Make sure of the following
That you have copied .env.example to .env
If you are using Facades, make sure that you enabled it inside bootstrap/app.php by uncommenting the line.
$app->withFacades();
Inside Lumen 5.2.8 either of the following would work.
The following will actually return a valid JSON object with the errors. You did not elaborate on your use case why that is not sufficient. What is nice with using the validate call like this is it actually returns a 422 http status code, which implies an unprocessed entity.
$app->get('/', function (Request $request) {
$this->validate($request, [
'name' => 'required'
]);
});
Using the facade works as well, albeit is returns a 200 status code.
$app->get('/', function (Request $request) {
$validator = Validator::make($request->only(['name']), [
'name' => 'required'
]);
if ($validator->fails()) {
return ['error' => 'Something went wrong'];
}
});
If you still do not come right with the Validator::make you can catch the default Validation exception using. It feels a little hacky.
$app->get('/', function (Request $request) {
try {
$this->validate($request, [
'name' => 'required'
]);
} catch (\Illuminate\Validation\ValidationException $e) {
// do whatever else you need todo for your use case
return ['error' => 'We caught the exception'];
}
});