# Buggy code
def get_url(path, repo=None, rev=None, remote=None):
    """
    Returns the URL to the storage location of a data file or directory tracked
    in a DVC repo. For Git repos, HEAD is used unless a rev argument is
    supplied. The default remote is tried unless a remote argument is supplied.

    Raises OutputNotFoundError if the file is not a dvc-tracked file.

    NOTE: This function does not check for the actual existence of the file or
    directory in the remote storage.
    """
    with _make_repo(repo, rev=rev) as _repo:
        path_info = PathInfo(_repo.root_dir) / path
        with reraise(FileNotFoundError, PathMissingError(path, repo)):
            metadata = _repo.repo_tree.metadata(path_info)

        if not metadata.is_dvc:
            raise OutputNotFoundError(path, repo)

        cloud = metadata.repo.cloud
        hash_info = _repo.repo_tree.get_hash(path_info)
        return cloud.get_url_for(remote, checksum=hash_info.value)


# Traceback (AttributeError)
Traceback (most recent call last):
File "x.py", line 6, in <module>
print(dvc.api.get_url("some_dir"))
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/api.py", line 37, in get_url
hash_info = _repo.repo_tree.get_hash(path_info)
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/tree/base.py", line 263, in get_hash
hash_info = self.get_dir_hash(path_info, **kwargs)
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/tree/repo.py", line 379, in get_dir_hash
return dvc_tree.get_dir_hash(path_info, **kwargs)
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/tree/dvc.py", line 242, in get_dir_hash
self._fetch_dir(out, **kwargs)
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/tree/dvc.py", line 146, in _fetch_dir
if self.fetch and out.changed_cache(filter_info=filter_info):
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/output/base.py", line 197, in changed_cache
self.hash_info, filter_info=filter_info
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/cache/base.py", line 412, in changed_cache
hash_info, path_info=path_info, filter_info=filter_info
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/cache/base.py", line 404, in _changed_dir_cache
if self.changed_cache_file(entry_hash):
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/cache/base.py", line 366, in changed_cache_file
actual = self.tree.get_hash(cache_info)
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/tree/base.py", line 242, in get_hash
hash_ = self.state.get(path_info)
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/state.py", line 408, in get
existing_record = self.get_state_record_for_inode(actual_inode)
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/state.py", line 352, in get_state_record_for_inode
self._execute(cmd, (self._to_sqlite(inode),))
File "/Users/matthieu/conda/lib/python3.6/site-packages/dvc/state.py", line 133, in _execute
return self.cursor.execute(cmd, parameters)
AttributeError: 'NoneType' object has no attribute 'execute'

# Fixed code
def get_url(path, repo=None, rev=None, remote=None):
    """
    Returns the URL to the storage location of a data file or directory tracked
    in a DVC repo. For Git repos, HEAD is used unless a rev argument is
    supplied. The default remote is tried unless a remote argument is supplied.

    Raises OutputNotFoundError if the file is not a dvc-tracked file.

    NOTE: This function does not check for the actual existence of the file or
    directory in the remote storage.
    """
    with _make_repo(repo, rev=rev) as _repo:
        path_info = PathInfo(_repo.root_dir) / path
        with reraise(FileNotFoundError, PathMissingError(path, repo)):
            metadata = _repo.repo_tree.metadata(path_info)

        if not metadata.is_dvc:
            raise OutputNotFoundError(path, repo)

        cloud = metadata.repo.cloud
        with _repo.state:
            hash_info = _repo.repo_tree.get_hash(path_info)
        return cloud.get_url_for(remote, checksum=hash_info.value)