# Buggy code
def objective_fun(params):
    global task_id
    exp_prefix = params.pop("exp_prefix")
    exp_name = "{exp}_{pid}_{id}".format(exp=exp_prefix, pid=os.getpid(), id=task_id)
    max_retries = params.pop("max_retries", 0) + 1
    result_timeout = params.pop("result_timeout")
    run_experiment_kwargs = params.pop("run_experiment_kwargs", {})

    func, eval_func = _get_stubs(params)

    result_success = False
    while max_retries > 0:
        _launch_ec2(func, exp_prefix, exp_name, params, run_experiment_kwargs)
        task_id += 1
        max_retries -= 1
        if _wait_result(exp_prefix, exp_name, result_timeout):
            result_success = True
            break
        elif max_retries > 0:
            print("Timed out waiting for results. Retrying...")

    if not result_success:
        print("Reached max retries, no results. Giving up.")
        return {"status": STATUS_FAIL}

    print("Results in! Processing.")
    result_dict = eval_func(exp_prefix, exp_name)
    result_dict["status"] = STATUS_OK
    result_dict["params"] = params
    return result_dict


# Traceback (TypeError)
Traceback (most recent call last):
File "/Users/jonathon/Documents/garage/garage/scripts/run_experiment.py", line 191, in <module>
run_experiment(sys.argv)
File "/Users/jonathon/Documents/garage/garage/scripts/run_experiment.py", line 146, in run_experiment
logger.log_parameters_lite(params_log_file, args)
File "/Users/jonathon/Documents/garage/garage/garage/misc/logger.py", line 372, in log_parameters_lite
json.dump(log_params, f, indent=2, sort_keys=True, cls=MyEncoder)
File "/anaconda2/envs/garage/lib/python3.6/json/__init__.py", line 179, in dump
for chunk in iterable:
File "/anaconda2/envs/garage/lib/python3.6/json/encoder.py", line 430, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "/anaconda2/envs/garage/lib/python3.6/json/encoder.py", line 404, in _iterencode_dict
yield from chunks
File "/anaconda2/envs/garage/lib/python3.6/json/encoder.py", line 404, in _iterencode_dict
yield from chunks
File "/anaconda2/envs/garage/lib/python3.6/json/encoder.py", line 404, in _iterencode_dict
yield from chunks
[Previous line repeated 1 more times]
File "/anaconda2/envs/garage/lib/python3.6/json/encoder.py", line 437, in _iterencode
o = _default(o)
File "/Users/jonathon/Documents/garage/garage/garage/misc/logger.py", line 352, in default
return json.JSONEncoder.default(self, o)
File "/anaconda2/envs/garage/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'TimeLimit' is not JSON serializable

# Fixed code
def objective_fun(params):
    global task_id
    exp_prefix = params.pop("exp_prefix")
    exp_name = "{exp}_{pid}_{id}".format(exp=exp_prefix, pid=os.getpid(), id=task_id)
    max_retries = params.pop("max_retries", 0) + 1
    result_timeout = params.pop("result_timeout")
    run_experiment_kwargs = params.pop("run_experiment_kwargs", {})

    func, eval_func = _extract_params(params)

    result_success = False
    while max_retries > 0:
        _launch_ec2(func, exp_prefix, exp_name, params, run_experiment_kwargs)
        task_id += 1
        max_retries -= 1
        if _wait_result(exp_prefix, exp_name, result_timeout):
            result_success = True
            break
        elif max_retries > 0:
            print("Timed out waiting for results. Retrying...")

    if not result_success:
        print("Reached max retries, no results. Giving up.")
        return {"status": STATUS_FAIL}

    print("Results in! Processing.")
    result_dict = eval_func(exp_prefix, exp_name)
    result_dict["status"] = STATUS_OK
    result_dict["params"] = params
    return result_dict