def get_val_err_msg_miss(dict_obj, attr_name, allowed_types, attr_default=None):
    """Get a value from the dictionary, produce a (more) readable
       error message when the value is missing or the type is wrong.

    :param dict_obj:       a dictionary of values
    :param attr_name:      key (attribute name)
    :param allowed_types:  allowed types
    :param attr_default:   default value

    :return: value or default (if specified)
    """
    if attr_name in dict_obj:
        val = dict_obj[attr_name]
        for t in allowed_types:
            if type(val) == t:
                return val

        raise Exception(f'Incorrect value type for the field: {attr_name}, expected types: ' +
                        ', '.join([str(t) for t in allowed_types]))
    else:
        if attr_default is not None:
            for t in allowed_types:
                if type(attr_default) == t:
                    return attr_default

                raise Exception(f'Incorrect type of the default value for the field: {attr_name}, expected types: ' +
                                ', '.join([str(t) for t in allowed_types]))

        raise Exception(f'Missing value for field: {attr_name}')