I have a question regarding PHP's way to handle exceptions and Laravel 5.
Here's a snippet of what I'm trying to accomplish
try
{
//set up webservices
saveData();
} catch(exception $e)
{
Log:error('stuff went bananas')
}
saveData(){
//record stuff through DB with eloquent
//in case some data is missing connect to a second DB
try
{
connect()
query to get data
}catch(exception $e)
{
//log error again
}
In other words, I'm calling webservices that receive data. I'm then inserting these into my own DB inside the Model.
At this stage I'm trying to see if I know the user ID that I just received. In case I don't I have to connect to a second database to request that same user.
There are two issues though
the second database I'm trying to connect isn't likely to be up
it will often not hold the information I need (I have to try again the next day)
There's nothing I can do against these issues. But what I want is for my code to try and connect, and in case it fails, log the errors and keep moving inserting the data.
Thanks in advance.
Related
Pretty new to laravel, so I'm not exactly sure how it handles errors and how best to catch them.
I'm using a 3rd party game server connection library that can query game servers in order to pull data such as players, current map etc..
This library is called Steam Condenser : https://github.com/koraktor/steam-condenser
I have imported this using composer in my project and all seems to be working fine, however I'm having trouble with catching exceptions that are thrown by the library.
One example is where the game server you are querying is offline.
Here is my code:
public function show($server_name)
{
try{
SteamSocket::setTimeout(3000);
$server = server::associatedServer($server_name);
$server_info = new SourceServer($server->server_ip);
$server_info->rconAuth($server->server_rcon);
$players = $server_info->getPlayers();
$total_players = count($players);
$more_info = $server_info->getServerInfo();
$maps = $server_info->rconExec('maps *');
preg_match_all("/(?<=fs\)).*?(?=\.bsp)/", $maps, $map_list);
}catch(SocketException $e){
dd("error");
}
return view('server', compact('server', 'server_info', 'total_players', 'players', 'more_info', 'map_list'));
}
If the server is offline, it will throw a SocketException, which I try to catch, however this never seems to happen. I then get the error page with the trace.
This causes a bit of a problem as I wish to simply tell the end user that the server is offline, however I cannot do this if I can't catch this error.
Is there something wrong with my try/catch? Does laravel handle catching errors in this way? Is this an issue with the 3rd party library?
A couple things:
Does the trace lead to the SocketException or to a different error? It's possible that a different error is being caught before the SocketException can be thrown.
Your catch statement is catching SocketException. Are you importing the full namespace at the top of your PHP file? use SteamCondenser\Exceptions\SocketException;
Also for debugging purposes, you could do an exception "catch all" and dump the type of exception:
try {
...
}catch(\Exception $e){
dd(get_class($e));
}
If you still get the stack trace after trying the above code, then an error is being thrown before the try/catch block starts.
This might be a silly question. I have two separate databases that are being used with Laravel 4. One of them can only be accessed with a certain IP (security reasons) while the other can be accessed. I have two different mysql connections. I have seen the Database connection test using this:
if(DB::connection('mysql')->getDatabaseName()){ }
To test what can be seen and what can't be seen, I tried to give the mysql a false password. I get this nice ugly error how it can't connect. Is there a way to make it where if the Database cannot be reached, just to ignore it? There's only one PHP class that's calling the secure only database on page load, but the above check doesn't seem to be working.
Going through the core code of laravel, there is no specific exceptions being thrown when a database connection fails.
The solution hence, is:
try {
//Strings always evaluate to boolean true
$dbConnected = (bool)DB::connection('mysql')->getDatabaseName();
}
catch (Exception $e)
{
$dbConnected = false;
}
Then work your code based on the variable $dbConnected.
Here is the problem
There is a script that after X amount of time (unknown amount between 5 and 40 minutes) throws the following error: MySQL server has gone away which Kohana turns into a Database_Exception 2006 As a result some of the information is not saved to the DB.
Here is what I think might work
class Model_Bar extends ORM {
protected $_belongs_to = array(
'foo' => array()
);
public function save(){ //Extends the save method
try {
$result = parent::save(); //Try parent save
} catch (Database_Exception $e) { //Catch exception
if ($e->getCode() == 2006) { //If exception code == 2006 then DB has gone away
mysqli_ping(); //Try to refresh DB link
$result = parent::save(); //Try parent save again
} else { //Exception code != 2006
throw new Exception($e); //Throw new DB exception
}
}
return $result; // Return the result from parent::save()
}
}
The Question: How can I refresh the link to the DB in Kohana's ORM?
More Info:
Using Kohana 3.0.8
Possible solution (I dont know how to try it in Kohana)
Thanks!
That's a problem of either
Reached the MYSQL configured timeout
Exceeded packet size
Loss of packets
If you are executing a long insert, like a bulk insert, if your DB isn't configured for that, no change in your code will have any effect. You may try to reconfigure your MYSQL instance, then rule out the MYSQL blame, then after you try to amend your code (which I doubt is the source of the problem). Retrying saving won't help much, but to make the DB even busier.
Another thing, if you are using a proxy (like HAProxy), check the timeouts on that as well.
I am utilizing Codeigniter.
I have developed a variety of features, and they work perfectly if used as intended.
One such script, a whois script checks the owner of a domain name.
If however the user types in an invalid domain name, all sorts of errors are being thrown up here there and everywhere.
For example, if a user types in stack.-com, this is of course not a valid domain. Thus when i call my helper which does the query, no result is return and a variety of errors are returned. There are also errors when i try to display an empty array to the user.
My question relates to errors.
I could use preg_match and check if the domain is valid. If not i set an error variable which i intend to output to the user.
However before my controller gets to the if else statement which decides whether to show the error page or the results page, the program is running queries, and accessing methods to get the data which were there no errors would get the data to pass to the result view.
I.E I know there is an error, but still lots of other errors are being shown because an invalid item is being passed to my other scripts.
With Codeigniter, and the MVC setup, what is the best way of catching the error and displaying it to the user without having to use exceptions which do the same thing over and over again?
Thanks
EDIT WITH IDEA
try
{
$this->load->model('whois');
$this->whois->process('domain.-com');
}
catch
{
$this->load->view('errors',$errordata);
$this->load->view('footer');
die;
}
$this->load->view('normal_content');
$this->load->view('footer');
Is this the suggested setup for using exceptions with codeigniter? within my model, the function will throw exceptions if there is a problem. The catch statement will then display them and die, thus not showing the content.. It does not seem right..?
Here's the way I usually handle this:
Post your form back to the same route
If there are errors, show the form again, with an error state
If everything passes, redirect NOW to the next step / success state
Sample code:
<?php
...
public function form()
{
if (strtoupper($this->input->server('REQUEST_METHOD')) == 'POST')
{
try {
// handle all your validation here
redirect('success_route');
exit;
}
catch (Exception $e)
{
// this could get a little fancier, but a simple solution is to pass the exception
// directly to the view. you could also load the `errors` view here, but return the
// content to a variable and pass to your full view
$this->load->vars('exception', $e);
}
}
$this->load->view('normal_content');
$this->load->view('footer');
}
...
You have to do as follows
1) database.php : $db['default']['db_debug'] = FALSE;
2) in your modal file
try {
$query_str = "SELECT * FROM `pro_property` WHERE username = '".$username."'";
$result = $this->db->query($query_str);
if (!$result)
{
throw new Exception('error in query');
return false;
}
return $result;
} catch (Exception $e) {
print_r($e);
}
I am using the Zend MVC framework along with an ORM layer generated with Propel, and I'm trying to figure out the best way to catch exceptions from a Propel object's save() function, and throw them to the Zend Form as errors.
Not all of the exceptions that come out of the Propel object have a way to identify which field caused the error, so I'm wondering if there is a way to add generic error messages to the entire form, rather than being forced to attach each error message to a particular form element.
For example, I have a save() call wrapped in a try/catch block, and I can add the exception->getMessage() to a form element's errors:
try {
$obj->save();
echo 'object saved successfully';
} catch (Exception $e) {
$form->name->addErrorMessage($e->getCode()." - ".$e->getMessage());
$form->name->markAsError();
$form->populate($formData);
}
but I would like to be able to do something like this:
try {
$obj->save();
echo 'object saved successfully';
} catch (Exception $e) {
$form->addErrorMessage($e->getCode()." - ".$e->getMessage());
$form->markAsError();
$form->populate($formData);
}
I hope that makes sense, thanks for the help,
Dave
Are you thinking about the errors from the database, or from the Propel validation layer (which isn't developed that much, and not used by default in the save() step)?
If you want to use the database errors, keep in mind that they will only return the first error (so the user has to submit four times if they entered three errors). Also, getting the field name out of the error message can be hard. Keep in mind that some keys cover multiple fields ("the combination of name and first_name must be unique").
This is why for example Symfony adds validation in the form layer. There, you can check all fields at once, and return multiple errors. But maybe you already do this, and only want this as a final check?