Laravel Eloquent Catch Special Expection - php

I'm currently trying the following: In my db, I have a column called templateURL, which is a unique key, so it may only exist once. Then if something tries to submit a form, where this is the same as already exist an error is thrown, saying
Integrity constraint violation: 1062 Duplicate entry for key 'templateURL'.
Of course it does, that's why I made the column unique. But: What I want is not the default Laravel Error, but getting back to the form with the values still entered and a message (alert from bootstrap for example or just a div next to the input field) saying that this already exist and asking to chooose another one. So I need to catch this exception and do something custom instead. How can I achieve what I want?

You've to wrap your database operation into a try-catch block and catch the error and do something else when you get a error, maybe redirect with old input data with a error message.
The error code for duplicate entry is 1062. So if you get 1062 as error code that means this data is a duplicate entry. Here is the code look like for catching this exception.
try {
$data = Model::create(array(
'templateURL' => 'some value ',
));
} catch (Illuminate\Database\QueryException $e) {
$errorCode = $e->errorInfo[1];
if($errorCode == 1062){
// we have a duplicate entry problem
}
}
Or if you wish not to handle the exception yourself, you can take help of Laravel Validator. Like following in your controller
// validation rules
$rules = array(
'templateURL' => 'unique:YourTableNameHere'
);
$validator = Validator::make(Input::all(), $rules);
// check if the validation failed
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
// redirect user back to the form with the errors from the validator
return Redirect::to('form')
->withErrors($validator);
} else {
// validation successful
$data = Model::create(array(
'templateURL' => 'some value ',
));
}
Then in your view template you can access the error messages via $errors variable.
Learn more about validation there https://laravel.com/docs/5.3/validation

Related

Add multiple custom messages in Laravel validation

I need to add multiple custom error messages like this and both needs to be displayed as validations messages. I have the following code :
if (!$condition1) {
$error[] = "Condition 1 needs to be satisfied";
$validation = false;
}
if (!$condition2) {
$error[] = "Condition 2 needs to be satisfied";
$validation = false;
}
$validator->setCustomMessages($error);
But here I am getting only one message that is the first one even if it is entering to second condition. I have tried to add $validator->setCustomMessages("Message"); in each of the conditions, but it is also doing the same thing.
Why are you using conditionals for validation?
This is what I use to handle validation for uploading photos in my controller.
You have a custom error message for 'required' and one for 'size' (which refers to the size of the photos array).
To add another custom message, just pipe on another rule and its corresponding error message using dot notation.
Only after all rules are satisfied then the code continues execution.
$this->validate($request,
[
'photos' => 'required|size:4'
],
[
'photos.required' => 'Photos are Required',
'photos.size' => 'You must upload 4 Photos'
]
);
Try to change $validator->setCustomMessages($error); for $validator->getMessageBag()->merge($error);
Now if you do $validator->errors()->getMessages() you must have your array with both errors

Catching a query exception?

I have a slug column in my database, it's unique.
If I try and store another row with a non unique slug I get a QueryException error.
I catch the error, and hope to return an error message something along the lines that "slug exists".
try {
User::create($data);
} catch (\Illuminate\Database\QueryException $e) {
//return the error
}
The above is fine, but I'm just wondering, what if another QueryException is thrown, not to do with the duplicate slug and i return a duplicate slug error message incorrectly.
Is there a way to find out what the query exception was and return an error message based on this? i know the exception provides its own message but I was hoping for something a little more user friendly.
To check if you got a QueryException because of a duplicate, check if $e->getCode() equals to 23000.
When a duplicate occurs due to a constraint, MySQL will issue signal SQLSTATE 23000 which you can use to determine what exactly went wrong. You can implement your own signal in MySQL to signal about various errors (via triggers etc)
Example:
try {
User::create($data);
} catch (\Illuminate\Database\QueryException $e) {
if($e->getCode() === '23000') {
// you got the duplicate
}
}
You can check errorInfo of the exception object
It looks like this..
+errorInfo: array:3 [▼
0 => "23000"
1 => 1062
2 => "Duplicate entry 'abc#gmail.com' for key 'users_email_unique'"
You can write following code in catch..
try{}
catch(QueryException $qe){
If ($qe->errorInfo[0] == "23000" && $qe->errorInfo[1] == "1062"){
return "Your message"
}else{
return "General Message"
}
}

Get error message from Laravel validation

I use Laravel built-in validator and I want to get the first error message
if ($validator->fails()) {
$error = $validator->messages()->toJson();
.....
}
This is the result when I print error
{"name":["The name must be at least 5 characters."],"alamat":["The address must be at least 5 characters."]}
In the example above, I want to get the first error, which is "The name must be at least 5 characters.". How can I do that?
Try this:
if ($validator->fails()) {
$error = $validator->errors()->first();
}
As per 2019 Laravel 5.8 and above to get all the error messages from the validator is as easy as this:
// create the validator and make a validation here...
if ($validator->fails()) {
$fieldsWithErrorMessagesArray = $validator->messages()->get('*');
}
You will get the array of arrays of the fields' names and error messages. Something like this:
[
'price'=>
[
0 => 'Price must be integer',
1 => 'Price must be greater than 0'
]
'password' => [
[
0 => 'Password is required'
]
]
]
You can use other validation messages getters that Illuminate\Support\MessageBag class provides (it is actually the object type that $validator->messages() above returns).
Message Bag Error Messages Additional Helpers
Go to your_laravel_project_dir/vendor/illuminate/support/MessageBag.php and find some useful methods like keys, has, hasAny, first, all, isEmpty etc. that you may need while checking for particular validation errors and customizing HTTP response messages.
It is easy to understand what they do by the look at the source code. Here is the Laravel 5.8 API reference though probably less useful than the source code.
In your ajax request, when you get the data, try data.name.
This will give you the error message for the name field.
$.ajax({
url: "/your-save-url",
type: "post",
data: serializedData,
success: function(data) { alert(data.name)}
});
If validation fails, the withErrors method can be used to flash the error messages to the session. This is an array and this method will automatically share $errors with all views after redirection.
return redirect('register')->withErrors($validator, 'login');
The MessageBag can be accessed using the instance from the $errors variable:
{{ $errors->login->first('email') }}
Form API docs
Hope this is helpful.
If you are using toastr style error displaying, this will work:
#if(session()->get('errors'))
toastr.error("{{ session()->get('errors')->first() }}");
#endif
for getting all errors, try this:
if ($validator->fails()) {
$error = $validator->errors()->all();
}
if you want to do it inside the controller you can:
Arr::first(Arr::flatten($validator->messages()->get('*')))
you will get the first text message
The email must be accepted.

Validating insert codeigniter

I'm trying to validating my insert data in codeigniter
The problem is the code returning me a duplicate entry's page error. And i want to throw that failure to home page with error message.
Here is my code:
$data = array(
'heheId' => $this->input->post('heheId'),
'userId' => $this->input->post('userId')
);
$this->db->insert('tentarasaya',$data);
if ($this->db->affected_rows() > 0){
$this->session->set_flashdata('info', "Hore sukses");
} else {
$this->session->set_flashdata('danger', "Fail insert");
}
redirect('my_home');
Any answer?
Update:
Duplicate entry like this
Try this
$data = array(
'heheId' => $this->input->post('heheId'),
'userId' => $this->input->post('userId')
);
if (!$this->db->insert('tentarasaya',$data)) { # add if here
# Unsuccessful
$this->session->set_flashdata('danger', "Fail insert");
}
else{
# Success
$this->session->set_flashdata('info', "Hore sukses");
}
redirect('my_home');
make sure that auto increment option is selected in your database. I am assuming that user_id here is a primary key, no need to insert that into a database yourself.
data = array(
'heheId' => $this->input->post('heheId'),
);
$this->db->insert('tentarasaya',$data);
Otherwise if you wish to insert user_ids yourself you can 1) define a custom call back function to check to see if the specified user id already exists in the database, 2) use the is_unique form validation rule that comes bundled with codeigniter

Drupal 7 db_update - checking for errors

I have a custom Drupal 7 module with an 'edit' page.
The form fields reference a couple of database tables, so to process the form, we attempt to update the first table, and we try to set a '$error' to 'true' and check against $error before we attempt to update the next table. For example:
HTML:
<input name="field1" />
<input name="field2" />
PHP:
$error = false;
$update_table_1 = db_update('table1')
->fields(array(
'field1' => $_POST['field1'],
))
->condition('id', $id)
->execute();
if(!update_table_1) {
$error = true;
}
if(!$error) {
$update_table_2 = db_update('table2')
->fields(array(
'field2' => $_POST['field2'],
))
->condition('id', $id)
->execute();
if(!$update_table_2) {
$error = true;
}
}
Problem: If only updating something in table 2, it will throw an error before it event gets to update table 2 because db_query says that it is not true since the field was the same as what was in the database (no change). Really, I only want to stop it if there was a database / code error.
Does the Drupal 7 db_update API have some kind of error reporting function like mysql_error()? Other suggestions?
The safest way you can do it is with a transaction and proper PHP error checking:
$transaction = db_transaction();
try {
// Query 1
db_update(...);
// Query 2
db_update(...);
}
catch (Exception $e) {
// Rollback the transaction
$transaction->rollback();
// Do something with the exception (inform user, etc)
}
I should mention the transaction is only necessary if you don't want the changes from the first query to persist if the second query fails. It's quite a common requirement but might not fit your use case.

Categories