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_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_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_err


@with_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_err


@with_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.2.1.tar.gz (4.3 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.2.1-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: with_err-1.2.1.tar.gz
  • Upload date:
  • Size: 4.3 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.2.1.tar.gz
Algorithm Hash digest
SHA256 b74f6895789d9c7ea642e6c5a7aa9ec72b7b72345dc0d3f584945c49d29bf83b
MD5 42ab6f21783343ee7ef4c94b9d8e1be6
BLAKE2b-256 54f2708a377775dad4d7d45c7cd264931cb4faaf0763ccb77ba61e576035e460

See more details on using hashes here.

File details

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

File metadata

  • Download URL: with_err-1.2.1-py3-none-any.whl
  • Upload date:
  • Size: 5.2 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.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b90619ffb7af771c9d620e735e271c1cb8db33b1b04f09765e949ca362b1c0be
MD5 77212daa4f4f32dd681540653cdd148f
BLAKE2b-256 ac60de416446ec01eb3ef985ad5561cc4cd1d00b4d806e358ebb3d23d21d8520

See more details on using hashes here.

Release history Release notifications | RSS feed

1.3.0

2 files

This release

1.2.1 This release

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