1) из класса Partner должно идти как минимум одно исключение PartnerException
все исключения в классе Partner будут "переварены в одно" PartnerException
в вашем случае вы можете добавить еще наследника и PartnerNotFoundException
логика становиться более лаконичной:
//App\Services\Partner
public function getSong(string $singer, string $song_name) : array
{
try {
$json = file_get_contents('partner-domain.com/api?singer=' . $singer);
} catch (\Exception $e) {
throw new PartnerException($e->getMessage());
}
$songs = json_decode($json, true);
//Filter songs by given name
$result = array_filter($songs, function($song) use ($song_name) {
return mb_strtolower($song['name'] === mb_strtolower($song_name));
});
//We need to return only 1 song
if (!isset($result[0])) {
throw new PartnerNotFoundException(sprintf(
'parnter not found by %s and %s', $singer, $song_name
));
}
return [
'status' => 'ok',
'data' => $result[0];
];
}
- в контроллере try catch если нужно поймать
public function getSong(string $singer, string $song_name) : string
{
try{
$song = $this->partnerService->getSong($singer, $song_name);
}
catch(PartnerNotFoundException $ex){
//п.с не помню как в лаевел но смысл поняли
return response()->status(404)->send();
}
return response()->json($song);
}
2) через конструктор
3) аналогично п1
4) метод называется getSong получить песню, это значит все альтернативные варианты загоняем в исключения, нет песни - исключение, ошибка сервиса, исключение