Как распознать криво порезанную строку?
$isValidUTF8 = ! (false === mb_detect_encoding($string, 'UTF-8', true));

Так же если json_encode() вернула false можно посмотреть json_last_error() и сравнить код ошибки с константой JSON_ERROR_UTF8
А что mb_substr использовать религия не позволяет?