tylercd100 / lern

LERN is a Laravel 5 package that will record exceptions into a database and will notify you via Email, Pushover or Slack.
MIT License
441 stars 37 forks source link

Error on app()->make("lern")->record($exception) #56

Open muzafarali opened 6 years ago

muzafarali commented 6 years ago

Hi, i'm using app()->make("lern")->record($exception); in render@Handler.php and getting error below many time ..

Next Tylercd100\LERN\Exceptions\RecorderFailedException: SQLSTATE[HY000] [1045] Access denied for user 'forge'@'localhost' (using password: NO) (SQL: insert into exceptions_log (class, file, line, code, message, trace, status_code, method, data, url, updated_at, created_at) values (Illuminate\Database\QueryException, H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Database\Connection.php, 647, 1045, SQLSTATE[HY000] [1045] Access denied for user 'forge'@'localhost' (using password: NO) (SQL: select from information_schema.tables where table_schema = forge and table_name = migrations), #0 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Database\Connection.php(607): Illuminate\Database\Connection->runQueryCallback('select from i...', Array, Object(Closure))

1 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Database\Connection.php(326): Illuminate\Database\Connection->run('select * from i...', Array, Object(Closure))

2 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Database\Schema\MySqlBuilder.php(18): Illuminate\Database\Connection->select('select * from i...', Array)

3 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php(221): Illuminate\Database\Schema\MySqlBuilder->hasTable('migrations')

4 H:\xampp\htdocs\zapro\passoinstructor\vendor\kordy\ticketit\src\TicketitServiceProvider.php(30): Illuminate\Support\Facades\Facade::__callStatic('hasTable', Array)

5 [internal function]: Kordy\Ticketit\TicketitServiceProvider->boot()

6 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(29): call_user_func_array(Array, Array)

7 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container{closure}()

8 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Container\BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))

9 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Container\Container.php(539): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)

10 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(788): Illuminate\Container\Container->call(Array)

11 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(771): Illuminate\Foundation\Application->bootProvider(Object(Kordy\Ticketit\TicketitServiceProvider))

12 [internal function]: Illuminate\Foundation\Application->Illuminate\Foundation{closure}(Object(Kordy\Ticketit\TicketitServiceProvider), 38)

13 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(772): array_walk(Array, Object(Closure))

14 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\BootProviders.php(17): Illuminate\Foundation\Application->boot()

15 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(208): Illuminate\Foundation\Bootstrap\BootProviders->bootstrap(Object(Illuminate\Foundation\Application))

16 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(162): Illuminate\Foundation\Application->bootstrapWith(Array)

17 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(146): Illuminate\Foundation\Http\Kernel->bootstrap()

18 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(116): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))

19 H:\xampp\htdocs\zapro\passoinstructor\public\index.php(52): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))

20 {main}, 0, GET, {"page":"3","name":""}, http://passoinstructor.dev/instructor/learner/skills/4, 2018-02-01 10:24:26, 2018-02-01 10:24:26)) in H:\xampp\htdocs\zapro\passoinstructor\vendor\tylercd100\lern\src\Components\Recorder.php:63

Stack trace:

0 H:\xampp\htdocs\zapro\passoinstructor\vendor\tylercd100\lern\src\LERN.php(67): Tylercd100\LERN\Components\Recorder->record(Object(Illuminate\Database\QueryException))

1 H:\xampp\htdocs\zapro\passoinstructor\app\Exceptions\Handler.php(68): Tylercd100\LERN\LERN->record(Object(Illuminate\Database\QueryException))

2 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(326): App\Exceptions\Handler->render(Object(Illuminate\Http\Request), Object(Illuminate\Database\QueryException))

3 H:\xampp\htdocs\zapro\passoinstructor\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(120): Illuminate\Foundation\Http\Kernel->renderException(Object(Illuminate\Http\Request), Object(Illuminate\Database\QueryException))

4 H:\xampp\htdocs\zapro\passoinstructor\public\index.php(52): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))

5 {main}

tylercd100 commented 6 years ago

Are you sure that your App can connect to your database? SQLSTATE[HY000] [1045] Access denied for user 'forge'@'localhost' (using password: NO)

muzafarali commented 6 years ago

Yes im sure my App is connected with database. And working on different things just for log i install your package and getting these errors many time in my log file..

muzafarali commented 6 years ago

i'm using laravel 5.4.x

EvilLooney commented 6 years ago

I just want to add that if the application cannot connect to the database and we have opted to record the errors in the database, we will enter an infinite loop that will cause the app to flood to the notification system (in my case, I got a thousands of emails until the app timed out).

A quick fix I used was to change the default reporting function to:

if ($this->shouldReport($exception)) {
    if (app()->bound('lern')) {
        if ($exception instanceof \Doctrine\DBAL\Driver\PDOException && 1045 == $exception->getCode()) {
            app()->make('lern')->notify($exception);
        } else {
            app()->make('lern')->handle($exception);
        }
    }
}
tylercd100 commented 6 years ago

Thank you EvilLooney!

I like this solution and I want to implement this and roll this out as a bug fix.

I am doing some reading on PDO error codes and it looks like the error codes are of type String according to the comments of this page (which explains the use of double equals in your code sample)

I also read that not every PDO driver utilizes the PDOException properly and may just pass "0" as the error code. People have suggested to use PDO::errorCode

So with that said, let me do some more testing today and get this bugger fixed.

-Tyler

EvilLooney commented 6 years ago

I also want to point out that my solution is only if we cannot connect to the database. I assume that this could also happen if the table does not exist or some other database error (I haven't tested).

Is there any way we could leverage your RecorderFailedException exception for this?

tylercd100 commented 6 years ago

Yes but it looks like with the current code it wont send a notification either. This could be changed.

tylercd100 commented 6 years ago

Alright, 4 hours later and I have an update.

  1. I made it so RecorderFailedException will get sent on the notification channels.
  2. I added a test that checks for infinite loops by having it try to connect to a database that is not running.
  3. I added a Rate limit that defaults to 1/notification/second. It uses the Cache driver that you have set for your environment. You can change this by setting the config value "lern.ratelimit"

I am going to run this on one of my project's staging servers to verify the infinite loop is gone.

I'll be back with an update

tylercd100 commented 6 years ago

Oops... forgot that merging pr's closes issues.

So version 4.5.0 is working as intended.

However in my case, if you use "database" as your queue driver paired with supervisor to restart your queue process whenever it fails. Supervisor tries to restart the process over and over which causes many notifications and memory overflow. This might be a bug related to laravel or supervisor, so I will look into it.

I'm not sure if your configuration is the same as mine @EvilLooney so let me know

tylercd100 commented 6 years ago

4.5.1 has fixed my previous issue.

EvilLooney commented 6 years ago

Good thinking for the supervisor / database queue driver combo.

However, we still have a problem if the Cache driver used is the database driver. My app completely crashes, even without some logging made into the laravel.log file.

tylercd100 commented 6 years ago

K I'll look into this too.

EvilLooney commented 5 years ago

Another problem we can have is that if, for some reason, the database has too many connections, we'll have a situation where we are flooding the database with INSERT queries (and sending out emails) which in turn exacerbates the too many connection problem.

Illuminate\Database\QueryException SQLSTATE[08004] [1040] Too many connections

Is there anyway to forgo all insertions of exceptions for these types of database problems?

tylercd100 commented 5 years ago

Hey EvilLooney,

Is the too many connections exception being thrown on this line? https://github.com/tylercd100/lern/blob/master/src/Components/Recorder.php#L77

Can you post a stack trace?

EvilLooney commented 5 years ago

I'm sorry! My bad.

Your code is working fine as it's not adding these errors in the exceptions table; I did get 200 or so emails though. I should have double checked.