# Buggy code
def _fftn(
    a,
    s,
    axes,
    norm,
    direction,
    value_type="C2C",
    order="A",
    plan=None,
    overwrite_x=False,
    out=None,
):
    if norm not in (None, "ortho"):
        raise ValueError('Invalid norm value %s, should be None or "ortho".' % norm)

    axes, axes_sorted = _prep_fftn_axes(a.ndim, s, axes, value_type)
    if not axes_sorted:
        if value_type == "C2C":
            return a
        else:
            raise IndexError("list index out of range")
    a = _convert_dtype(a, value_type)

    if order == "A":
        if a.flags.f_contiguous:
            order = "F"
        elif a.flags.c_contiguous:
            order = "C"
        else:
            a = cupy.ascontiguousarray(a)
            order = "C"
    elif order not in ["C", "F"]:
        raise ValueError("Unsupported order: {}".format(order))

    # Note: need to call _cook_shape prior to sorting the axes
    a = _cook_shape(a, s, axes, value_type, order=order)

    if order == "C" and not a.flags.c_contiguous:
        a = cupy.ascontiguousarray(a)
    elif order == "F" and not a.flags.f_contiguous:
        a = cupy.asfortranarray(a)

    # _cook_shape tells us input shape only, and not output shape
    out_size = _get_fftn_out_size(a.shape, s, axes_sorted[-1], value_type)

    a = _exec_fftn(
        a,
        direction,
        value_type,
        norm=norm,
        axes=axes_sorted,
        overwrite_x=overwrite_x,
        plan=plan,
        out=out,
        out_size=out_size,
    )
    return a


# Traceback (ValueError)
np.fft.fft(np.array([]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<__array_function__ internals>", line 5, in fft
File "/path/to/python3.8/site-packages/numpy-1.18.2-py3.8-linux-x86_64.egg/numpy/fft/_pocketfft.py", line 188, in fft
output = _raw_fft(a, n, axis, False, True, inv_norm)
File "/path/to/python3.8/site-packages/numpy-1.18.2-py3.8-linux-x86_64.egg/numpy/fft/_pocketfft.py", line 57, in _raw_fft
raise ValueError("Invalid number of FFT data points (%d) specified."
ValueError: Invalid number of FFT data points (0) specified.
cupy.fft.fft(cupy.array([]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/to/cupy/cupy/fft/fft.py", line 496, in fft
return _fft(a, (n,), (axis,), norm, cupy.cuda.cufft.CUFFT_FORWARD)
File "/path/to/cupy/cupy/fft/fft.py", line 175, in _fft
a = _fft_c2c(a, direction, norm, axes, overwrite_x, plan=plan)
File "/path/to/cupy/cupy/fft/fft.py", line 142, in _fft_c2c
a = _exec_fft(a, direction, 'C2C', norm, axis, overwrite_x, plan=plan)
File "/path/to/cupy/cupy/fft/fft.py", line 91, in _exec_fft
batch = a.size // a.shape[-1]
ZeroDivisionError: integer division or modulo by zero
cupy.fft.fft(cupy.array([]), n=0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/to/cupy/cupy/fft/fft.py", line 496, in fft
return _fft(a, (n,), (axis,), norm, cupy.cuda.cufft.CUFFT_FORWARD)
File "/path/to/cupy/cupy/fft/fft.py", line 155, in _fft
raise ValueError(
ValueError: Invalid number of FFT data points (0) specified.

# Fixed code
def _fftn(
    a,
    s,
    axes,
    norm,
    direction,
    value_type="C2C",
    order="A",
    plan=None,
    overwrite_x=False,
    out=None,
):
    if norm not in (None, "ortho"):
        raise ValueError('Invalid norm value %s, should be None or "ortho".' % norm)

    axes, axes_sorted = _prep_fftn_axes(a.ndim, s, axes, value_type)
    if not axes_sorted:
        if value_type == "C2C":
            return a
        else:
            raise IndexError("list index out of range")
    a = _convert_dtype(a, value_type)

    if order == "A":
        if a.flags.f_contiguous:
            order = "F"
        elif a.flags.c_contiguous:
            order = "C"
        else:
            a = cupy.ascontiguousarray(a)
            order = "C"
    elif order not in ["C", "F"]:
        raise ValueError("Unsupported order: {}".format(order))

    # Note: need to call _cook_shape prior to sorting the axes
    a = _cook_shape(a, s, axes, value_type, order=order)

    for n in a.shape:
        if n < 1:
            raise ValueError("Invalid number of FFT data points (%d) specified." % n)

    if order == "C" and not a.flags.c_contiguous:
        a = cupy.ascontiguousarray(a)
    elif order == "F" and not a.flags.f_contiguous:
        a = cupy.asfortranarray(a)

    # _cook_shape tells us input shape only, and not output shape
    out_size = _get_fftn_out_size(a.shape, s, axes_sorted[-1], value_type)

    a = _exec_fftn(
        a,
        direction,
        value_type,
        norm=norm,
        axes=axes_sorted,
        overwrite_x=overwrite_x,
        plan=plan,
        out=out,
        out_size=out_size,
    )
    return a