Most db errors can't be caught up before request exit.
This method runs on shutdown and look if there're errors in `$EZSQL_ERROR`
global var and log them if so.

@param array $args

@return LogDataInterface

@wp-hook shutdown
193365
public function update( array $args ) {

		/** @var array $EZSQL_ERROR */
		global $EZSQL_ERROR;
		if ( empty( $EZSQL_ERROR ) ) {
			return new NullLog();
		}

		$errors  = $EZSQL_ERROR;
		$last    = end( $errors );
		$context = [ 'last_query' => $last[ 'query' ], 'errors' => $errors, ];

		return new Error( $last[ 'error_str' ], Channels::DB, $context );
	}
1206313
public function init($args = null){
		/*
		echo __METHOD__.__LINE__.'<br>'.PHP_EOL;
		echo __METHOD__.__LINE__.'get_class<pre>['.var_export(get_class($this), true).']</pre>'.'<br>'.PHP_EOL; 
		echo __METHOD__.__LINE__.'get_parent_class<pre>['.var_export(get_parent_class(__CLASS__), true).']</pre>'.'<br>'.PHP_EOL; 
		echo __METHOD__.__LINE__.'<br>'.PHP_EOL;
		echo __METHOD__.__LINE__.'get_class_methods<pre>['.var_export(get_class_methods($this), true).']</pre>'.'<br>'.PHP_EOL; 
		*/
		#parent::__construct($this->logConfig);
		
		$this->logConfig = $GLOBALS["CONFIG_MANAGER"]->getSetting('AUTH','AUDIT','CLIENT_LOG');
		
		parent::__construct($args);
		return;
	}
965511
public function adm_login($args) {
		$this->init();
		$logger = $this->logger;

		if ($this->store_is_logged_in())
			return [AdminStoreError::USER_ALREADY_LOGGED_IN];

		if (!isset($args['post']))
			return [AdminStoreError::DATA_INCOMPLETE];
		if (!Common::check_idict($args['post'], ['uname', 'upass']))
			return [AdminStoreError::DATA_INCOMPLETE];
		extract($args['post']);

		$usalt = $this->store->query(
			"SELECT usalt FROM udata WHERE uname=? LIMIT 1",
			[$uname]);
		if (!$usalt)
			# user not found
			return [AdminStoreError::USER_NOT_FOUND];
		$usalt = $usalt['usalt'];

		$udata = $this->store_match_password($uname, $upass, $usalt);
		if (!$udata) {
			# wrong password
			$logger->warning(
				"Zapmin: login: wrong password: '$uname'.");
			return [AdminStoreError::WRONG_PASSWORD];
		}

		// generate token
		$token = $this->generate_secret(
			$upass . $usalt . time(), $usalt);

		$sid = $this->store->insert('usess', [
			'uid'   => $udata['uid'],
			'token' => $token,
		], 'sid');
		if ($this->dbtype == 'mysql') {
			// mysql has no parametrized default values, and can't
			// invoke trigger on currently inserted table
			$expire_at = $this->store->stmt_fragment('datetime', [
				'delta' => $this->expiration,
			]);
			$this->store->query_raw(sprintf(
				"UPDATE usess SET expire=(%s) WHERE sid='%s'",
				$expire_at, $sid));
		}

		// token must be used by the router; this is a subset
		// of return value of get_safe_user_data() so it needs
		// a re-request after signing in
		$logger->info("Zapmin: login: OK: '$uname'.");
		return [0, [
			'uid' => $udata['uid'],
			'uname' => $udata['uname'],
			'token' => $token,
		]];
	}
937473
private static function exec(array $args)
    {
        $cmd = implode(' ', array_map('escapeshellarg', $args)) . ' 2>/dev/null';
        $process = proc_open($cmd, [1 => ['pipe', 'w']], $pipes);
        $output = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        if (proc_close($process) !== 0) {
            return false;
        }

        return $output;
    }
841911
public function execute($args)
    {
        self::$definedProps = new Properties();
        $this->searchForThis = null;

        // 1) First handle any options which should always
        // Note: The order in which these are executed is important (if multiple of these options are specified)

        if (in_array('-help', $args) || in_array('-h', $args)) {
            static::printUsage();

            return;
        }

        if (in_array('-version', $args) || in_array('-v', $args)) {
            static::printVersion();

            return;
        }

        if (in_array('-init', $args) || in_array('-i', $args)) {
            $key = array_search('-init', $args) ?: array_search('-i', $args);
            $path = isset($args[$key + 1]) ? $args[$key + 1] : null;

            self::init($path);

            return;
        }

        if (in_array('-diagnostics', $args)) {
            Diagnostics::doReport(new PrintStream(self::$out));

            return;
        }

        // 2) Next pull out stand-alone args.
        // Note: The order in which these are executed is important (if multiple of these options are specified)

        if (false !== ($key = array_search('-quiet', $args, true)) || false !== ($key = array_search(
            '-q',
            $args,
            true
        ))
        ) {
            self::$msgOutputLevel = Project::MSG_WARN;
            unset($args[$key]);
        }

        if (false !== ($key = array_search('-emacs', $args, true))
            || false !== ($key = array_search('-e', $args, true))
        ) {
            $this->emacsMode = true;
            unset($args[$key]);
        }

        if (false !== ($key = array_search('-verbose', $args, true))) {
            self::$msgOutputLevel = Project::MSG_VERBOSE;
            unset($args[$key]);
        }

        if (false !== ($key = array_search('-debug', $args, true))) {
            self::$msgOutputLevel = Project::MSG_DEBUG;
            unset($args[$key]);
        }

        if (false !== ($key = array_search('-silent', $args, true))
            || false !== ($key = array_search('-S', $args, true))
        ) {
            $this->silent = true;
            unset($args[$key]);
        }

        if (false !== ($key = array_search('-propertyfileoverride', $args, true))) {
            $this->propertyFileOverride = true;
            unset($args[$key]);
        }

        // 3) Finally, cycle through to parse remaining args
        //
        $keys = array_keys($args); // Use keys and iterate to max(keys) since there may be some gaps
        $max = $keys ? max($keys) : -1;
        for ($i = 0; $i <= $max; $i++) {
            if (!array_key_exists($i, $args)) {
                // skip this argument, since it must have been removed above.
                continue;
            }

            $arg = $args[$i];

            if ($arg == "-logfile") {
                try {
                    // see: http://phing.info/trac/ticket/65
                    if (!isset($args[$i + 1])) {
                        $msg = "You must specify a log file when using the -logfile argument\n";
                        throw new ConfigurationException($msg);
                    }

                    $logFile = new PhingFile($args[++$i]);
                    $out = new FileOutputStream($logFile); // overwrite
                    self::setOutputStream($out);
                    self::setErrorStream($out);
                    self::$isLogFileUsed = true;
                } catch (IOException $ioe) {
                    $msg = "Cannot write on the specified log file. Make sure the path exists and you have write permissions.";
                    throw new ConfigurationException($msg, $ioe);
                }
            } elseif ($arg == "-buildfile" || $arg == "-file" || $arg == "-f") {
                if (!isset($args[$i + 1])) {
                    $msg = "You must specify a buildfile when using the -buildfile argument.";
                    throw new ConfigurationException($msg);
                }

                $this->buildFile = new PhingFile($args[++$i]);
            } elseif ($arg == "-listener") {
                if (!isset($args[$i + 1])) {
                    $msg = "You must specify a listener class when using the -listener argument";
                    throw new ConfigurationException($msg);
                }

                $this->listeners[] = $args[++$i];
            } elseif (StringHelper::startsWith("-D", $arg)) {
                // Evaluating the property information //
                // Checking whether arg. is not just a switch, and next arg. does not starts with switch identifier
                if (('-D' == $arg) && (!StringHelper::startsWith('-', $args[$i + 1]))) {
                    $name = $args[++$i];
                } else {
                    $name = substr($arg, 2);
                }

                $value = null;
                $posEq = strpos($name, "=");
                if ($posEq !== false) {
                    $value = substr($name, $posEq + 1);
                    $name = substr($name, 0, $posEq);
                } elseif ($i < count($args) - 1 && !StringHelper::startsWith("-D", $args[$i + 1])) {
                    $value = $args[++$i];
                }
                self::$definedProps->setProperty($name, $value);
            } elseif ($arg == "-logger") {
                if (!isset($args[$i + 1])) {
                    $msg = "You must specify a classname when using the -logger argument";
                    throw new ConfigurationException($msg);
                }

                $this->loggerClassname = $args[++$i];
            } elseif ($arg == "-no-strict") {
                $this->strictMode = false;
            } elseif ($arg == "-strict") {
                $this->strictMode = true;
            } elseif ($arg == "-inputhandler") {
                if ($this->inputHandlerClassname !== null) {
                    throw new ConfigurationException("Only one input handler class may be specified.");
                }
                if (!isset($args[$i + 1])) {
                    $msg = "You must specify a classname when using the -inputhandler argument";
                    throw new ConfigurationException($msg);
                }

                $this->inputHandlerClassname = $args[++$i];
            } elseif ($arg === "-propertyfile") {
                $i = $this->handleArgPropertyFile($args, $i);
            } elseif ($arg === "-keep-going" || $arg === "-k") {
                $this->keepGoingMode = true;
            } elseif ($arg == "-longtargets") {
                self::$definedProps->setProperty('phing.showlongtargets', 1);
            } elseif ($arg == "-projecthelp" || $arg == "-targets" || $arg == "-list" || $arg == "-l" || $arg == "-p") {
                // set the flag to display the targets and quit
                $this->projectHelp = true;
            } elseif ($arg == "-find") {
                // eat up next arg if present, default to build.xml
                if ($i < count($args) - 1) {
                    $this->searchForThis = $args[++$i];
                } else {
                    $this->searchForThis = self::DEFAULT_BUILD_FILENAME;
                }
            } elseif (substr($arg, 0, 1) == "-") {
                // we don't have any more args
                self::printUsage();
                self::$err->write(PHP_EOL);
                throw new ConfigurationException("Unknown argument: " . $arg);
            } else {
                // if it's no other arg, it may be the target
                $this->targets[] = $arg;
            }
        }

        // if buildFile was not specified on the command line,
        if ($this->buildFile === null) {
            // but -find then search for it
            if ($this->searchForThis !== null) {
                $this->buildFile = $this->_findBuildFile(self::getProperty("user.dir"), $this->searchForThis);
            } else {
                $this->buildFile = new PhingFile(self::DEFAULT_BUILD_FILENAME);
            }
        }

        try {
            // make sure buildfile (or buildfile.dist) exists
            if (!$this->buildFile->exists()) {
                $distFile = new PhingFile($this->buildFile->getAbsolutePath() . ".dist");
                if (!$distFile->exists()) {
                    throw new ConfigurationException(
                        "Buildfile: " . $this->buildFile->__toString() . " does not exist!"
                    );
                }
                $this->buildFile = $distFile;
            }

            // make sure it's not a directory
            if ($this->buildFile->isDirectory()) {
                throw new ConfigurationException("Buildfile: " . $this->buildFile->__toString() . " is a dir!");
            }
        } catch (IOException $e) {
            // something else happened, buildfile probably not readable
            throw new ConfigurationException("Buildfile: " . $this->buildFile->__toString() . " is not readable!");
        }

        $this->loadPropertyFiles();

        $this->readyToRun = true;
    }
992541
public function setBreakpoint(array $args)
    {
        $breakpointArgs = $this->pluckArray([
            'action',
            'condition',
            'expressions',
            'logMessageFormat',
            'logLevel',
            'location'
        ], $args);
        return $this->send([$this->debuggerClient, 'setBreakpoint'], [
            $this->pluck('debuggeeId', $args),
            $this->serializer->decodeMessage(new Breakpoint(), $breakpointArgs),
            DebuggerClient::getDefaultAgentVersion(),
            $args
        ]);
    }
208123
public function logError($line, $args = self::NO_ARGUMENTS)
	{
        $this->log($line, self::ERR, $args);
    }
365672
public function run(array $args = null) {
		$exec = escapeshellcmd($this->command);
		if ($args) {
			$exec .= " ". implode(" ", array_map("escapeshellarg", (array) $args));
		}
		
		if ($this->sudo) {
			$this->suExec(sprintf($this->sudo." 2>&1", $exec), $this->verbose);
		} elseif ($this->verbose) {
			ob_start(function($s) {
				$this->output .= $s;
				return $s;
			}, 1);
			passthru($exec, $this->status);
			ob_end_flush();
		} elseif ($this->verbose !== false /* !quiet */) {
			ob_start([$this, "progress"], 1);
			passthru($exec . " 2>&1", $this->status);
			ob_end_flush();
		} else {
			exec($exec ." 2>&1", $output, $this->status);
			$this->output = implode("\n", $output);
		}
		
		if ($this->status) {
			throw new Exception("Command {$exec} failed ({$this->status})");
		}

		return $this;
	}
842089
public function get( array $args = [], array $assoc_args = [] ) {

		$site_id = (int) $args[ 0 ];
		$site    = get_blog_details( $site_id );
		if ( ! $site ) {
			WP_CLI::error( "A site with ID {$site_id} does not exist" );
		}

		// trailing-slash it, as URLs ends always with a trailing slash in context of the wp_blogs table
		WP_CLI::line( trailingslashit( $site->siteurl ) );
		exit( 0 );
	}
440479
public function error($message, $args=array())
    {
        $backtrace        = debug_backtrace();
        $args['FILENAME'] = $backtrace[0]['file'];
        $args['LINENO']   = $backtrace[0]['line'];
        $this->log($message, $args, 'LOG_ERR');

    }
258423
public function addError(string $msg, string ...$args): void
    {
        $this->errors[] = sprintf($msg, ...$args);
    }
279599
public function error($e): void
  {
    $this->has_error = true;
    self::has_error();
    $msg = [
      self::$line,
      self::get_log_line('ERROR DB!'),
      self::$line
    ];
    if ( \is_string($e) ){
      $msg[] = self::get_log_line('USER MESSAGE');
      $msg[] = $e;
    }
    else if ( method_exists($e, 'getMessage') ){
      $msg[] = self::get_log_line('DB MESSAGE');
      $msg[] = $e->getMessage();
    }
    $this->last_error = end($msg);
    $msg[] = self::get_log_line('QUERY');
    $msg[] = $this->last();
    if ( $this->last_params['values'] ){
      $msg[] =  self::get_log_line('VALUES');
      foreach ( $this->last_params['values'] as $v ){
        if ( $v === null ){
          $msg[] = 'NULL';
        }
        else if ( \is_bool($v) ){
          $msg[] = $v ? 'TRUE' : 'FALSE';
        }
        else if ( \is_string($v) ){
          $msg[] = str::is_buid($v) ? bin2hex($v) : str::cut($v, 30);
        }
        else{
          $msg[] = $v;
        }
      }
    }
    $msg[] =  self::get_log_line('BACKTRACE');
    $dbt = array_reverse(debug_backtrace());
    array_walk($dbt, function($a, $i) use(&$msg){
      $msg[] = str_repeat(' ', $i).($i ? '->' : '')."{$a['function']}  (".basename(dirname($a['file'])).'/'.basename($a['file']).":{$a['line']})";
    });
    $this->log(implode(PHP_EOL, $msg));
    if ( $this->on_error === self::E_DIE ){
      die(\defined('BBN_IS_DEV') && BBN_IS_DEV ? '<pre>'.PHP_EOL.implode(PHP_EOL, $msg).PHP_EOL.'</pre>' : 'Database error');
    }
  }
1193096
public function call($args = [])
    {
        $command = $this->listener->get('setname');
        if (!$command)
            throw new NoticeException('SetupCommand: "setname" command is not registered in ayuco.');
            
        try {
            $this->_lineBreak();
            $this->_print('------------------------------');
            $this->_lineBreak();
            $this->_print('Wordpress MVC (AYUCO) Setup');
            $this->_lineBreak();
            // NAMESPACE || PROJECT NAME
            $this->_print('------------------------------');
            $this->_lineBreak();
            $this->_print('Enter your project\'s namespace (example: MyProject):');
            $this->_lineBreak();
            $namespace = $this->listener->getInput();
            $command->setName(empty($namespace)
                ? 'MyApp'
                : str_replace(' ', '', ucwords($namespace))
            );
            // TYPE
            $this->_print('------------------------------');
            $this->_lineBreak();
            $this->_print('Enter your project\'s type (options: "theme" or "plugin"):');
            $this->_lineBreak();
            $type = $this->listener->getInput();
            $this->setType($type);
            // DESCRIPTION
            $this->_print('------------------------------');
            $this->_lineBreak();
            $this->getDescription();
            $this->_lineBreak();
            // End
            $this->_print('------------------------------');
            $this->_lineBreak();
            $this->_print('Your plugin namespace is "%s"', $namespace);
            $this->_lineBreak();
            $this->_print('Setup completed!');
            $this->_lineBreak();
            $this->_print('------------------------------');
            $this->_lineBreak();
        } catch (NoticeException $e) {
            throw new NoticeException('Command "setup": Failed! ' . $e->getMessage());
        }
    }
512126
public function error($value, ...$args) {
        return call_user_func_array(
            [__CLASS__, 'event'],
            array_merge([self::ERROR, $value], $args)
        );
    }
572462
public function sql( $args ) {
		list( $table_name ) = $args;
		$rows = Model::$list;
		if ( ! isset( $rows[ $table_name ] ) ) {
			\WP_CLI::error( sprintf( '%s: table is not registered.', $table_name ) );
		}
		$model = $rows[ $table_name ];
		if ( ! class_exists( $model ) ) {
			\WP_CLI::error( sprintf( '%s: Model class does not exist.', $model ) );
		}
		if ( ! $this->is_sub_class_of( $model, Model::class ) ) {
			\WP_CLI::error( sprintf( '%s is not sub class of %s.', $model, Model::class ) );
		}
		/** @var Model $instance */
		$instance = $model::get_instance();
		\WP_CLI::line( sprintf( '%s: Version %s', $instance->table, $instance->version ) );
		$query = $instance->get_tables_schema( $instance->current_version() );
		echo "\n" . $query . "\n\n";
		\WP_CLI::success( sprintf( '%s letters', number_format_i18n( strlen( $query ) ) ) );
	}
1298412
public function update( array $args ) {

		$wp = $args ? reset( $args ) : NULL;

		if ( ! $wp instanceof \WP ) {
			return new NullLog();
		}

		$error = [];
		isset( $wp->query_vars[ 'error' ] ) and $error[] = $wp->query_vars[ 'error' ];
		is_404() and $error[] = '404 Page not found';

		if ( empty( $error ) ) {
			return new NullLog();
		}

		$url     = filter_var( add_query_arg( [] ), FILTER_SANITIZE_URL );
		$message = "Error on frontend request for url {$url}.";
		$context = [
			'error'        => $error,
			'query_vars'   => $wp->query_vars,
			'matched_rule' => $wp->matched_rule,
		];

		return new Debug( $message, Channels::HTTP, $context );
	}
649651
public function error()
	{
		// We need this because the error info is discarded by the
		// server the first time you request it, and query() already
		// calls error() once for logging purposes when a query fails.
		static $error = array('code' => 0, 'message' => NULL);

		$message = mssql_get_last_message();
		if ( ! empty($message))
		{
			$error['code']    = $this->query('SELECT @@ERROR AS code')->row()->code;
			$error['message'] = $message;
		}

		return $error;
	}