Skip to main content

with-err

with-err is a python library that converts try-except pattern into Go-like result, err pattern. I feel result, err pattern easier to maintain in large projects.

Getting Started

Install

pip install with-err

(with uv)

uv pip install with-err

Use as Function

import json
from with_err import with_err

json_loads_e = with_err(json.loads)

data, err = json_loads_e('{"a": 1}')
assert err is None
assert data == {"a": 1}

data, err = json_loads_e('{"a": }')
assert isinstance(err, json.decoder.JSONDecodeError)
assert data is None

Use as Decorator

import json
from with_err import with_err

@with_err
def json_loads_e(a: str):
    return json.loads(a)

data, err = json_loads_e('{"a": 1}')
assert err is None
assert data == {"a": 1}

data, err = json_loads_e('{"a": }')
assert isinstance(err, json.decoder.JSONDecodeError)
assert data is None

with_err with Specified Exceptions

Return err only with specified exceptions and raise other exceptions.

import json
from with_err import with_err

@with_err(json.decoder.JSONDecodeError)
def json_loads_e(a: str):
    return json.loads(a)

data, err = json_loads_e('{"a": 1}')
assert err is None
assert data == {"a": 1}

data, err = json_loads_e('{"a": }')
assert isinstance(err, json.decoder.JSONDecodeError)
assert data is None
# raise json.decoder.JSONDecodeError

import json
import re
from with_err import with_err

@with_err(re.PatternError)
def json_loads_e(a: str):
    return json.loads(a)

data, err = json_loads_e('{"a": }')
# function

import json
from with_err import with_err

json_loads_e = with_err(json.decoder.JSONDecodeError)(json.loads)

data, err = json_loads_e('{"a": 1}')
assert err is None
assert data == {"a": 1}

data, err = json_loads_e('{"a": }')
assert isinstance(err, json.decoder.JSONDecodeError)
assert data is None
# empty: return all Exceptions

import json
from with_err import with_err

json_loads_e = with_err()(json.loads)

data, err = json_loads_e('{"a": 1}')
assert err is None
assert data == {"a": 1}

data, err = json_loads_e('{"a": }')
assert isinstance(err, json.decoder.JSONDecodeError)
assert data is None

Async Functions

from with_err import with_async_err

async def async_fetch_data(endpoint: str) -> dict[str, str]:
    if endpoint == "bad":
        raise ValueError("Failed to reach endpoint")
    return {"status": "ok"}

async_fetch_data_e = with_async_err(async_fetch_data)
res, err = await async_fetch_data_e("bad")
assert isinstance(err, ValueError)
assert res is None

Generators

from with_err import with_gen_err


@with_gen_err
def my_stream():
    yield 1
    raise ValueError('invalid')

for idx, (each, err) in enumerate(my_stream()):
    if idx == 0:
        assert each == 1
        assert err is None
    else:
        assert each is None
        assert isinstance(err, ValueError)

Async Generators

from with_err import with_async_gen_err


@with_async_gen_err
async def my_async_stream():
    yield 1
    raise ValueError('invalid')

async for each, err in my_async_stream():
    if each == 1:
        assert each == 1
        assert err is None
    else:
        assert each is None
        assert isinstance(err, ValueError)

Functions Returning list or tuple

@with_err
def my_list_func(is_good=False):
    if not is_good:
        raise ValueError('not good')
    return [1, 2]

data, err = my_list_func()
assert data is None
assert isinstance(err, ValueError)

data, err = my_list_func(True)
assert data is not None
assert err is None
item1, item2 = data
assert item1 == 1
assert item2 == 2

Get err Traceback Stack

import json
from with_err import with_err, get_err_strs


@with_err
def json_loads_e(a: str):
    return json.loads(a)

_data, err = json_loads_e('{"a": 1}')
err_stack = get_err_strs(err)
assert err is None
assert err_stack == []
import json
import re
from with_err import with_err, get_err_strs


@with_err
def json_loads_e(a: str):
    return json.loads(a)

_data, err = json_loads_e('{"a": }')
err_stack = get_err_strs(err)
err_str = '\n'.join(err_stack)
assert isinstance(err, json.decoder.JSONDecodeError)
assert len(err_stack) > 0
assert re.search(r', line \d+, in json_loads_e', err_str)
assert re.search(r'json/__init__.py", line \d+, in loads', err_str)
assert 'json.decoder.JSONDecodeError: Expecting value:' in err_str

Raise err

import json
import re
from with_err import with_err, get_err_strs, raise_err


@with_err
def json_loads_e(a: str):
    return json.loads(a)

def gen_err():
    data, err = json_loads_e('{"a": }')
    return data, raise_err(err)

data, err = gen_err()
err_stack = get_err_strs(err)
err_str = '\n'.join(err_stack)
assert isinstance(err, json.decoder.JSONDecodeError)
assert len(err_stack) > 0
assert re.search(r', line \d+, in gen_err', err_str)
assert re.search(r', line \d+, in json_loads_e', err_str)
assert re.search(r'json/__init__.py", line \d+, in loads', err_str)
assert 'json.decoder.JSONDecodeError: Expecting value:' in err_str

Raise err with Continuous @with_err

import json
import re
from with_err import with_err, get_err_strs, raise_err


@with_err
def json_loads_e(a: str):
    return json.loads(a)


@with_err
def gen_err():
    data, err = json_loads_e('{"a": }')
    if err is not None:
        raise err
    return data

data, err = gen_err()
err_stack = get_err_strs(err)
err_str = '\n'.join(err_stack)
assert isinstance(err, json.decoder.JSONDecodeError)
assert len(err_stack) > 0
assert re.search(r', line \d+, in gen_err', err_str)
assert re.search(r', line \d+, in json_loads_e', err_str)
assert re.search(r'json/__init__.py", line \d+, in loads', err_str)
assert 'json.decoder.JSONDecodeError: Expecting value:' in err_str

Acknowledgement

The implementation is based on the following Gemini / ChatGPT suggestions:

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

with_err-1.3.0.tar.gz (4.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

with_err-1.3.0-py3-none-any.whl (5.4 kB view details)

Uploaded Python 3

File details

Details for the file with_err-1.3.0.tar.gz.

File metadata

  • Download URL: with_err-1.3.0.tar.gz
  • Upload date:
  • Size: 4.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for with_err-1.3.0.tar.gz
Algorithm Hash digest
SHA256 0438c32138369369d52548b72d1a7ade0490442eb9f29185e87c0cb965796869
MD5 241f06f4ec1c502997b0d9e3606c313c
BLAKE2b-256 96fd23aff0225629f2150b97f9eb7d67a4b8a018d56f4051cac6d5301772a28a

See more details on using hashes here.

File details

Details for the file with_err-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: with_err-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 5.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for with_err-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 53a49a6534b8f6711ec54bd43b491cdd11ca63caf0d504384afce7500fc953bf
MD5 d0498ef60ffd1429de8e625164f0d917
BLAKE2b-256 7922a963d6a0bd27ace951cb218a856f69ea5ff8125f7decb83eccbc557c5069

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.3.0 This release

2 files

1.2.1

2 files

1.2.0

2 files

1.1.0

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page