1

I have a problem that when I query a database and get zero results, I get an empty array, though I want to throw a 'ModelNotFoundException'. Here is my sample code:

<?php
#App\Http\Controller\MainController
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\ModelNotFoundException;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Demo;
use DB;


class MainController extends Controller
{

  public function getTagRecords($tag, $limit)
  {
    try{
        $results = Demo::getRecordsByTag($tag, $limit);
    }catch (Illuminate\Database\Eloquent\ModelNotFoundException $e){
        return response()->json(['message'=>'hello there error'], 404);
    }
    return $results;
  }

I am sending a request via AJAX and want to return an error message and status. I have not modified the Handler class.

Here is the Model code:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;  
use DB;

class Demo extends Model
{

    public static function getRecordsByTag($tag, $limit)
    {
        $params = [
            'tag' => $tag, 
            'limit' => $limit,
        ];

        return  DB::select("SELECT d.idDemo, d.idUsuario, u.Referencia, d.Uri_fichero,
            (SELECT Nombre FROM Edad_voz WHERE IdEdad_voz = d.IdEdad_voz) Edad_voz,
            (SELECT Nombre FROM Tono_voz WHERE idTono_voz = d.idTono_voz) Tono_voz,
            (SELECT Idioma_Variante FROM Idioma WHERE idIdioma = d.idIdioma) Idioma,
            (SELECT Nombre FROM Genero WHERE idGenero = d.idGenero) Genero

            FROM Demo AS d
            INNER JOIN logs AS l ON d.idDemo = l.idElemento
            INNER JOIN usuario AS u ON d.idUsuario = u.idUsuario

            WHERE

            l.accion = :tag AND
            l.procesado = '0'

            ORDER BY idDemo

            LIMIT :limit;", $params);
    }
}
1
  • Can you share the Demo::getRecordsByTag($tag, $limit) code with us? Commented Nov 9, 2015 at 14:33

2 Answers 2

2

I would rewrite your getRecordsByTag function to take care if it like this:

    $result = DB::select("SELECT d.idDemo, d.idUsuario, u.Referencia, d.Uri_fichero,
        (SELECT Nombre FROM Edad_voz WHERE IdEdad_voz = d.IdEdad_voz) Edad_voz,
        (SELECT Nombre FROM Tono_voz WHERE idTono_voz = d.idTono_voz) Tono_voz,
        (SELECT Idioma_Variante FROM Idioma WHERE idIdioma = d.idIdioma) Idioma,
        (SELECT Nombre FROM Genero WHERE idGenero = d.idGenero) Genero

        FROM Demo AS d
        INNER JOIN logs AS l ON d.idDemo = l.idElemento
        INNER JOIN usuario AS u ON d.idUsuario = u.idUsuario

        WHERE

        l.accion = :tag AND
        l.procesado = '0'

        ORDER BY idDemo

        LIMIT :limit;", $params);

    if (is_empty($result)) throw new ModelNotFoundException;

    return $result;

So basically: If your result is empty throw the exception. Your controller shouldn't need any modification with this.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, for the reply. I have started to think that I should just return an empty response no matter what regardless of my app logic. Though now I think - that should depend on situation and I can decide myself if I want to throw an exception or return an empty query result.
0

first you'd better remove the comment before the namespace: #App\Http\Controller\MainController

second you can and should check if the class exists and then throw an exception manually

depending on the PHP version you're using you should be able to do something like:

if (class_exists(Demo::class)) {
    $results = Demo::getRecordsByTag($tag, $limit);
} else {
    // or you can throw an exception from here
    // throw new Illuminate\Database\Eloquent\ModelNotFoundException('hello there error');
    return response()->json(['message'=>'hello there error'], 404);
}

UPDATE: I just saw you've provided the code behind the getRecordsByTag() method call. I'd say add documentation to the method to explain that it can return an empty response e.g. array() and than it's up to the caller to decide how to handle the specific case leaving your Model clean and with no business logic. So in the caller check if the result is empty collection and if that's the case throw an exception as that is specific logic required for its functioning.

if (count($results = Demo::getRecordsByTag($tag, $limit)) === 0) {
    throw new RecordNotFoundException("Tag: $tag was not found in the Demo table");
}

4 Comments

thats not a namespace, thats the name of the file. The namespace is right below. Also - why should I check if the class exists? I am looking if there are any records with the parameters and want to throw an exception if the query returns 0 records like in the ->findOrFail method.
yeah sorry ignore the comment regarding the line above namespace, my mistake. If Demo::getRecordsByTag() throws an exception you should be able to catch it as long as it's of the same type ModelNotFoundException if the query though returns 0 you should check that and throw/return on your own.
So if the method returns an empty array, I should throw an error myself?
@naneri presumably if there is successful response e.g. 0 and not an exception you can either throw an exception or return the error response. Up to you. Not sure what happens inside Demo::getRecordsByTag() but if it's not throwing there's nothing to catch :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.