Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can json_encode trigger a catch block? [duplicate]

Tags:

json

php

This is probably a really simple question, but I just can't find any info on it.

I work with a system that aggregates a lot of data from various sources and then stores that data in a database. For the most part, the system works fine, but occasionally we get an issue where data can have awkward character encoding (for instance, when the data is in another language, like French) that our system doesn't like.

The data gets passed to our processing server (we use Gearman), and to ensure that all the info pertaining to source gets passed we json_encode an array with everything we need. My question to you is: if I wrap the json_encode in a try/catch block, will things that cause "PHP Warning: json_encode(): Invalid UTF-8 sequence in argument" messages trigger the catch block to activate?

Thanks!

like image 719
Lisa Avatar asked Sep 04 '12 14:09

Lisa


3 Answers

No but you can check it's return value in a function and throw an exception when something goes wrong. You can also use json_last_error to get details on the error

Example:

function my_json_encode($data) {
    if( json_encode($data) === false ) {
        throw new Exception( json_last_error() );
    }
}

try {
    my_json_encode($data);
}
catch(Exception $e ) {
    // do something
}

I do find it highly annoying that to get the actual error message you have to check a list of constants that is returned from json_last_error(). In the past I've used a switch / case statement to make that happen but you could throw different exceptions depending on the error.

like image 128
Cfreak Avatar answered Oct 23 '22 02:10

Cfreak


Not natively, you will need to set up some custom error handling.

<?php

function exception_error_handler($errno, $errstr, $errfile, $errline)
{
    throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}

set_error_handler('exception_error_handler');

Then you can do:

try
{
    json_encode(...);
}
catch (ErrorException $e)
{
    // do some thing with $e->getMessage()
}

But bare in mind that this will cause all PHP errors to throw an exception, so you should fine tune it to your needs.

like image 43
Matt Humphrey Avatar answered Oct 23 '22 01:10

Matt Humphrey


You can also Output errors or show exception on basis of errors. Like see code below.

<?php


protected static $_messages = array(
    JSON_ERROR_NONE => 'No error has occurred',
    JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded',
    JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
    JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
    JSON_ERROR_SYNTAX => 'Syntax error',
    JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
);

public static function encode($value, $options = 0) {
    $result = json_encode($value, $options);

    if($result)  {
        return $result;
    }

    throw new RuntimeException(static::$_messages[json_last_error()]);
}

public static function decode($json, $assoc = false) {
    $result = json_decode($json, $assoc);

    if($result) {
        return $result;
    }

    throw new RuntimeException(static::$_messages[json_last_error()]);
}
like image 41
Hasnat Safder Avatar answered Oct 23 '22 01:10

Hasnat Safder