# Buggy code
def find_embed(self, url, max_width=None):
    # Find provider
    endpoint = self._get_endpoint(url)
    if endpoint is None:
        raise EmbedNotFoundException

    # Work out params
    params = self.options.copy()
    params["url"] = url
    params["format"] = "json"
    if max_width:
        params["maxwidth"] = max_width

    # Perform request
    request = Request(endpoint + "?" + urlencode(params))
    request.add_header("User-agent", "Mozilla/5.0")
    try:
        r = urllib_request.urlopen(request)
    except URLError:
        raise EmbedNotFoundException
    oembed = json.loads(r.read().decode("utf-8"))

    # Convert photos into HTML
    if oembed["type"] == "photo":
        html = '<img src="%s" alt="">' % (oembed["url"],)
    else:
        html = oembed.get("html")

    # Return embed as a dict
    return {
        "title": oembed["title"] if "title" in oembed else "",
        "author_name": oembed["author_name"] if "author_name" in oembed else "",
        "provider_name": oembed["provider_name"] if "provider_name" in oembed else "",
        "type": oembed["type"],
        "thumbnail_url": oembed.get("thumbnail_url"),
        "width": oembed.get("width"),
        "height": oembed.get("height"),
        "html": html,
    }


# Traceback (json.decoder.JSONDecodeError)
Internal Server Error: /admin/pages/127028/edit/
Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.8/dist-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/wagtail/admin/urls/__init__.py", line 127, in wrapper
return view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/wagtail/admin/auth.py", line 193, in decorated_view
return view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/wagtail/admin/views/pages/edit.py", line 131, in dispatch
return super().dispatch(request)
File "/usr/local/lib/python3.8/dist-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/usr/local/lib/python3.8/dist-packages/wagtail/admin/views/pages/edit.py", line 217, in post
if self.form.is_valid() and not self.page_perms.page_locked():
File "/usr/local/lib/python3.8/dist-packages/modelcluster/forms.py", line 316, in is_valid
form_is_valid = super(ClusterForm, self).is_valid()
File "/usr/local/lib/python3.8/dist-packages/django/forms/forms.py", line 177, in is_valid
return self.is_bound and not self.errors
File "/usr/local/lib/python3.8/dist-packages/django/forms/forms.py", line 172, in errors
self.full_clean()
File "/usr/local/lib/python3.8/dist-packages/django/forms/forms.py", line 374, in full_clean
self._clean_fields()
File "/usr/local/lib/python3.8/dist-packages/django/forms/forms.py", line 392, in _clean_fields
value = field.clean(value)
File "/usr/local/lib/python3.8/dist-packages/wagtail/core/blocks/base.py", line 571, in clean
return self.block.clean(value)
File "/usr/local/lib/python3.8/dist-packages/wagtail/core/blocks/stream_block.py", line 202, in clean
(child.block.name, child.block.clean(child.value), child.id)
File "/usr/local/lib/python3.8/dist-packages/wagtail/core/blocks/struct_block.py", line 130, in clean
result.append((name, self.child_blocks[name].clean(val)))
File "/usr/local/lib/python3.8/dist-packages/wagtail/embeds/blocks.py", line 69, in clean
if isinstance(value, EmbedValue) and not value.html:
File "/usr/local/lib/python3.8/dist-packages/django/utils/functional.py", line 48, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/usr/local/lib/python3.8/dist-packages/wagtail/embeds/blocks.py", line 22, in html
return embed_to_frontend_html(self.url)
File "/usr/local/lib/python3.8/dist-packages/wagtail/embeds/format.py", line 9, in embed_to_frontend_html
embed = embeds.get_embed(url)
File "/usr/local/lib/python3.8/dist-packages/wagtail/embeds/embeds.py", line 24, in get_embed
embed_dict = finder(url, max_width)
File "/usr/local/lib/python3.8/dist-packages/wagtail/embeds/embeds.py", line 20, in finder
return finder.find_embed(url, max_width=max_width)
File "/usr/local/lib/python3.8/dist-packages/wagtail/embeds/finders/oembed.py", line 65, in find_embed
oembed = json.loads(r.read().decode('utf-8'))
File "/usr/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

# Fixed code
def find_embed(self, url, max_width=None):
    # Find provider
    endpoint = self._get_endpoint(url)
    if endpoint is None:
        raise EmbedNotFoundException

    # Work out params
    params = self.options.copy()
    params["url"] = url
    params["format"] = "json"
    if max_width:
        params["maxwidth"] = max_width

    # Perform request
    request = Request(endpoint + "?" + urlencode(params))
    request.add_header("User-agent", "Mozilla/5.0")
    try:
        r = urllib_request.urlopen(request)
        oembed = json.loads(r.read().decode("utf-8"))
    except (URLError, json.decoder.JSONDecodeError):
        raise EmbedNotFoundException

    # Convert photos into HTML
    if oembed["type"] == "photo":
        html = '<img src="%s" alt="">' % (oembed["url"],)
    else:
        html = oembed.get("html")

    # Return embed as a dict
    return {
        "title": oembed["title"] if "title" in oembed else "",
        "author_name": oembed["author_name"] if "author_name" in oembed else "",
        "provider_name": oembed["provider_name"] if "provider_name" in oembed else "",
        "type": oembed["type"],
        "thumbnail_url": oembed.get("thumbnail_url"),
        "width": oembed.get("width"),
        "height": oembed.get("height"),
        "html": html,
    }