We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Raise error when trying to write empty dataframes
Currently, the behavior when writing an empty dataframe is counter-intuitive (`ValueError: Geometry column cannot contain mutiple geometry types when writing to file.`). Would it be possible to add  a check and more helpful exception?  

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `geopandas/io/file.py`
Content:
```
1 import os
2 
3 import fiona
4 import numpy as np
5 import six
6 
7 from geopandas import GeoDataFrame
8 
9 # Adapted from pandas.io.common
10 if six.PY3:
11     from urllib.request import urlopen as _urlopen
12     from urllib.parse import urlparse as parse_url
13     from urllib.parse import uses_relative, uses_netloc, uses_params
14 else:
15     from urllib2 import urlopen as _urlopen
16     from urlparse import urlparse as parse_url
17     from urlparse import uses_relative, uses_netloc, uses_params
18 
19 _VALID_URLS = set(uses_relative + uses_netloc + uses_params)
20 _VALID_URLS.discard('')
21 
22 
23 def _is_url(url):
24     """Check to see if *url* has a valid protocol."""
25     try:
26         return parse_url(url).scheme in _VALID_URLS
27     except:
28         return False
29 
30 
31 def read_file(filename, **kwargs):
32     """
33     Returns a GeoDataFrame from a file or URL.
34 
35     Parameters
36     ----------
37     filename: str
38         Either the absolute or relative path to the file or URL to
39         be opened.
40     **kwargs:
41         Keyword args to be passed to the `open` or `BytesCollection` method
42         in the fiona library when opening the file. For more information on
43         possible keywords, type:
44         ``import fiona; help(fiona.open)``
45 
46     Examples
47     --------
48     >>> df = geopandas.read_file("nybb.shp")
49 
50     Returns
51     -------
52     geodataframe : GeoDataFrame
53     """
54     bbox = kwargs.pop('bbox', None)
55     if _is_url(filename):
56         req = _urlopen(filename)
57         path_or_bytes = req.read()
58         reader = fiona.BytesCollection
59     else:
60         path_or_bytes = filename
61         reader = fiona.open
62 
63     with reader(path_or_bytes, **kwargs) as features:
64         crs = features.crs
65         if bbox is not None:
66             assert len(bbox) == 4
67             f_filt = features.filter(bbox=bbox)
68         else:
69             f_filt = features
70 
71         columns = list(features.meta["schema"]["properties"]) + ["geometry"]
72         gdf = GeoDataFrame.from_features(f_filt, crs=crs, columns=columns)
73 
74     return gdf
75 
76 
77 def to_file(df, filename, driver="ESRI Shapefile", schema=None,
78             **kwargs):
79     """
80     Write this GeoDataFrame to an OGR data source
81 
82     A dictionary of supported OGR providers is available via:
83     >>> import fiona
84     >>> fiona.supported_drivers
85 
86     Parameters
87     ----------
88     df : GeoDataFrame to be written
89     filename : string
90         File path or file handle to write to.
91     driver : string, default 'ESRI Shapefile'
92         The OGR format driver used to write the vector file.
93     schema : dict, default None
94         If specified, the schema dictionary is passed to Fiona to
95         better control how the file is written. If None, GeoPandas
96         will determine the schema based on each column's dtype
97 
98     The *kwargs* are passed to fiona.open and can be used to write
99     to multi-layer data, store data within archives (zip files), etc.
100     """
101     if schema is None:
102         schema = infer_schema(df)
103     filename = os.path.abspath(os.path.expanduser(filename))
104     with fiona.drivers():
105         with fiona.open(filename, 'w', driver=driver, crs=df.crs,
106                         schema=schema, **kwargs) as colxn:
107             colxn.writerecords(df.iterfeatures())
108 
109 
110 def infer_schema(df):
111     try:
112         from collections import OrderedDict
113     except ImportError:
114         from ordereddict import OrderedDict
115 
116     def convert_type(column, in_type):
117         if in_type == object:
118             return 'str'
119         out_type = type(np.asscalar(np.zeros(1, in_type))).__name__
120         if out_type == 'long':
121             out_type = 'int'
122         if out_type == 'bool':
123             raise ValueError('column "{}" is boolean type, '.format(column) +
124                              'which is unsupported in file writing. '
125                              'Consider casting the column to int type.')
126         return out_type
127 
128     properties = OrderedDict([
129         (col, convert_type(col, _type)) for col, _type in
130         zip(df.columns, df.dtypes) if col != df._geometry_column_name
131     ])
132 
133     geom_type = _common_geom_type(df)
134     if not geom_type:
135         raise ValueError("Geometry column cannot contain mutiple "
136                          "geometry types when writing to file.")
137 
138     schema = {'geometry': geom_type, 'properties': properties}
139 
140     return schema
141 
142 
143 def _common_geom_type(df):
144     # Need to check geom_types before we write to file...
145     # Some (most?) providers expect a single geometry type:
146     # Point, LineString, or Polygon
147     geom_types = df.geometry.geom_type.unique()
148 
149     from os.path import commonprefix
150     # use reversed geom types and commonprefix to find the common suffix,
151     # then reverse the result to get back to a geom type
152     geom_type = commonprefix([g[::-1] for g in geom_types if g])[::-1]
153     if not geom_type:
154         return None
155 
156     if df.geometry.has_z.any():
157         geom_type = "3D " + geom_type
158 
159     return geom_type
160
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/geopandas/io/file.py b/geopandas/io/file.py
--- a/geopandas/io/file.py
+++ b/geopandas/io/file.py
@@ -130,7 +130,11 @@
         zip(df.columns, df.dtypes) if col != df._geometry_column_name
     ])
 
+    if df.empty:
+        raise ValueError("Cannot write empty DataFrame to file.")
+
     geom_type = _common_geom_type(df)
+    
     if not geom_type:
         raise ValueError("Geometry column cannot contain mutiple "
                          "geometry types when writing to file.")

{"golden_diff": "diff --git a/geopandas/io/file.py b/geopandas/io/file.py\n--- a/geopandas/io/file.py\n+++ b/geopandas/io/file.py\n@@ -130,7 +130,11 @@\n         zip(df.columns, df.dtypes) if col != df._geometry_column_name\n     ])\n \n+    if df.empty:\n+        raise ValueError(\"Cannot write empty DataFrame to file.\")\n+\n     geom_type = _common_geom_type(df)\n+    \n     if not geom_type:\n         raise ValueError(\"Geometry column cannot contain mutiple \"\n                          \"geometry types when writing to file.\")\n", "issue": "Raise error when trying to write empty dataframes\nCurrently, the behavior when writing an empty dataframe is counter-intuitive (`ValueError: Geometry column cannot contain mutiple geometry types when writing to file.`). Would it be possible to add  a check and more helpful exception?  \n", "before_files": [{"content": "import os\n\nimport fiona\nimport numpy as np\nimport six\n\nfrom geopandas import GeoDataFrame\n\n# Adapted from pandas.io.common\nif six.PY3:\n    from urllib.request import urlopen as _urlopen\n    from urllib.parse import urlparse as parse_url\n    from urllib.parse import uses_relative, uses_netloc, uses_params\nelse:\n    from urllib2 import urlopen as _urlopen\n    from urlparse import urlparse as parse_url\n    from urlparse import uses_relative, uses_netloc, uses_params\n\n_VALID_URLS = set(uses_relative + uses_netloc + uses_params)\n_VALID_URLS.discard('')\n\n\ndef _is_url(url):\n    \"\"\"Check to see if *url* has a valid protocol.\"\"\"\n    try:\n        return parse_url(url).scheme in _VALID_URLS\n    except:\n        return False\n\n\ndef read_file(filename, **kwargs):\n    \"\"\"\n    Returns a GeoDataFrame from a file or URL.\n\n    Parameters\n    ----------\n    filename: str\n        Either the absolute or relative path to the file or URL to\n        be opened.\n    **kwargs:\n        Keyword args to be passed to the `open` or `BytesCollection` method\n        in the fiona library when opening the file. For more information on\n        possible keywords, type:\n        ``import fiona; help(fiona.open)``\n\n    Examples\n    --------\n    >>> df = geopandas.read_file(\"nybb.shp\")\n\n    Returns\n    -------\n    geodataframe : GeoDataFrame\n    \"\"\"\n    bbox = kwargs.pop('bbox', None)\n    if _is_url(filename):\n        req = _urlopen(filename)\n        path_or_bytes = req.read()\n        reader = fiona.BytesCollection\n    else:\n        path_or_bytes = filename\n        reader = fiona.open\n\n    with reader(path_or_bytes, **kwargs) as features:\n        crs = features.crs\n        if bbox is not None:\n            assert len(bbox) == 4\n            f_filt = features.filter(bbox=bbox)\n        else:\n            f_filt = features\n\n        columns = list(features.meta[\"schema\"][\"properties\"]) + [\"geometry\"]\n        gdf = GeoDataFrame.from_features(f_filt, crs=crs, columns=columns)\n\n    return gdf\n\n\ndef to_file(df, filename, driver=\"ESRI Shapefile\", schema=None,\n            **kwargs):\n    \"\"\"\n    Write this GeoDataFrame to an OGR data source\n\n    A dictionary of supported OGR providers is available via:\n    >>> import fiona\n    >>> fiona.supported_drivers\n\n    Parameters\n    ----------\n    df : GeoDataFrame to be written\n    filename : string\n        File path or file handle to write to.\n    driver : string, default 'ESRI Shapefile'\n        The OGR format driver used to write the vector file.\n    schema : dict, default None\n        If specified, the schema dictionary is passed to Fiona to\n        better control how the file is written. If None, GeoPandas\n        will determine the schema based on each column's dtype\n\n    The *kwargs* are passed to fiona.open and can be used to write\n    to multi-layer data, store data within archives (zip files), etc.\n    \"\"\"\n    if schema is None:\n        schema = infer_schema(df)\n    filename = os.path.abspath(os.path.expanduser(filename))\n    with fiona.drivers():\n        with fiona.open(filename, 'w', driver=driver, crs=df.crs,\n                        schema=schema, **kwargs) as colxn:\n            colxn.writerecords(df.iterfeatures())\n\n\ndef infer_schema(df):\n    try:\n        from collections import OrderedDict\n    except ImportError:\n        from ordereddict import OrderedDict\n\n    def convert_type(column, in_type):\n        if in_type == object:\n            return 'str'\n        out_type = type(np.asscalar(np.zeros(1, in_type))).__name__\n        if out_type == 'long':\n            out_type = 'int'\n        if out_type == 'bool':\n            raise ValueError('column \"{}\" is boolean type, '.format(column) +\n                             'which is unsupported in file writing. '\n                             'Consider casting the column to int type.')\n        return out_type\n\n    properties = OrderedDict([\n        (col, convert_type(col, _type)) for col, _type in\n        zip(df.columns, df.dtypes) if col != df._geometry_column_name\n    ])\n\n    geom_type = _common_geom_type(df)\n    if not geom_type:\n        raise ValueError(\"Geometry column cannot contain mutiple \"\n                         \"geometry types when writing to file.\")\n\n    schema = {'geometry': geom_type, 'properties': properties}\n\n    return schema\n\n\ndef _common_geom_type(df):\n    # Need to check geom_types before we write to file...\n    # Some (most?) providers expect a single geometry type:\n    # Point, LineString, or Polygon\n    geom_types = df.geometry.geom_type.unique()\n\n    from os.path import commonprefix\n    # use reversed geom types and commonprefix to find the common suffix,\n    # then reverse the result to get back to a geom type\n    geom_type = commonprefix([g[::-1] for g in geom_types if g])[::-1]\n    if not geom_type:\n        return None\n\n    if df.geometry.has_z.any():\n        geom_type = \"3D \" + geom_type\n\n    return geom_type\n", "path": "geopandas/io/file.py"}], "after_files": [{"content": "import os\n\nimport fiona\nimport numpy as np\nimport six\n\nfrom geopandas import GeoDataFrame\n\n# Adapted from pandas.io.common\nif six.PY3:\n    from urllib.request import urlopen as _urlopen\n    from urllib.parse import urlparse as parse_url\n    from urllib.parse import uses_relative, uses_netloc, uses_params\nelse:\n    from urllib2 import urlopen as _urlopen\n    from urlparse import urlparse as parse_url\n    from urlparse import uses_relative, uses_netloc, uses_params\n\n_VALID_URLS = set(uses_relative + uses_netloc + uses_params)\n_VALID_URLS.discard('')\n\n\ndef _is_url(url):\n    \"\"\"Check to see if *url* has a valid protocol.\"\"\"\n    try:\n        return parse_url(url).scheme in _VALID_URLS\n    except:\n        return False\n\n\ndef read_file(filename, **kwargs):\n    \"\"\"\n    Returns a GeoDataFrame from a file or URL.\n\n    Parameters\n    ----------\n    filename: str\n        Either the absolute or relative path to the file or URL to\n        be opened.\n    **kwargs:\n        Keyword args to be passed to the `open` or `BytesCollection` method\n        in the fiona library when opening the file. For more information on\n        possible keywords, type:\n        ``import fiona; help(fiona.open)``\n\n    Examples\n    --------\n    >>> df = geopandas.read_file(\"nybb.shp\")\n\n    Returns\n    -------\n    geodataframe : GeoDataFrame\n    \"\"\"\n    bbox = kwargs.pop('bbox', None)\n    if _is_url(filename):\n        req = _urlopen(filename)\n        path_or_bytes = req.read()\n        reader = fiona.BytesCollection\n    else:\n        path_or_bytes = filename\n        reader = fiona.open\n\n    with reader(path_or_bytes, **kwargs) as features:\n        crs = features.crs\n        if bbox is not None:\n            assert len(bbox) == 4\n            f_filt = features.filter(bbox=bbox)\n        else:\n            f_filt = features\n\n        columns = list(features.meta[\"schema\"][\"properties\"]) + [\"geometry\"]\n        gdf = GeoDataFrame.from_features(f_filt, crs=crs, columns=columns)\n\n    return gdf\n\n\ndef to_file(df, filename, driver=\"ESRI Shapefile\", schema=None,\n            **kwargs):\n    \"\"\"\n    Write this GeoDataFrame to an OGR data source\n\n    A dictionary of supported OGR providers is available via:\n    >>> import fiona\n    >>> fiona.supported_drivers\n\n    Parameters\n    ----------\n    df : GeoDataFrame to be written\n    filename : string\n        File path or file handle to write to.\n    driver : string, default 'ESRI Shapefile'\n        The OGR format driver used to write the vector file.\n    schema : dict, default None\n        If specified, the schema dictionary is passed to Fiona to\n        better control how the file is written. If None, GeoPandas\n        will determine the schema based on each column's dtype\n\n    The *kwargs* are passed to fiona.open and can be used to write\n    to multi-layer data, store data within archives (zip files), etc.\n    \"\"\"\n    if schema is None:\n        schema = infer_schema(df)\n    filename = os.path.abspath(os.path.expanduser(filename))\n    with fiona.drivers():\n        with fiona.open(filename, 'w', driver=driver, crs=df.crs,\n                        schema=schema, **kwargs) as colxn:\n            colxn.writerecords(df.iterfeatures())\n\n\ndef infer_schema(df):\n    try:\n        from collections import OrderedDict\n    except ImportError:\n        from ordereddict import OrderedDict\n\n    def convert_type(column, in_type):\n        if in_type == object:\n            return 'str'\n        out_type = type(np.asscalar(np.zeros(1, in_type))).__name__\n        if out_type == 'long':\n            out_type = 'int'\n        if out_type == 'bool':\n            raise ValueError('column \"{}\" is boolean type, '.format(column) +\n                             'which is unsupported in file writing. '\n                             'Consider casting the column to int type.')\n        return out_type\n\n    properties = OrderedDict([\n        (col, convert_type(col, _type)) for col, _type in\n        zip(df.columns, df.dtypes) if col != df._geometry_column_name\n    ])\n\n    if df.empty:\n        raise ValueError(\"Cannot write empty DataFrame to file.\")\n\n    geom_type = _common_geom_type(df)\n    \n    if not geom_type:\n        raise ValueError(\"Geometry column cannot contain mutiple \"\n                         \"geometry types when writing to file.\")\n\n    schema = {'geometry': geom_type, 'properties': properties}\n\n    return schema\n\n\ndef _common_geom_type(df):\n    # Need to check geom_types before we write to file...\n    # Some (most?) providers expect a single geometry type:\n    # Point, LineString, or Polygon\n    geom_types = df.geometry.geom_type.unique()\n\n    from os.path import commonprefix\n    # use reversed geom types and commonprefix to find the common suffix,\n    # then reverse the result to get back to a geom type\n    geom_type = commonprefix([g[::-1] for g in geom_types if g])[::-1]\n    if not geom_type:\n        return None\n\n    if df.geometry.has_z.any():\n        geom_type = \"3D \" + geom_type\n\n    return geom_type\n", "path": "geopandas/io/file.py"}]}