catch errors in multiple places that might be destroying the async flow and causing lnbits to die silently.
This commit is contained in:
parent
b48a44bcd0
commit
fdf4f6c1ae
9 changed files with 82 additions and 55 deletions
|
|
@ -33,6 +33,10 @@ class PaymentFailure(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvoiceFailure(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
async def create_invoice(
|
async def create_invoice(
|
||||||
*,
|
*,
|
||||||
wallet_id: str,
|
wallet_id: str,
|
||||||
|
|
@ -50,7 +54,7 @@ async def create_invoice(
|
||||||
amount=amount, memo=invoice_memo, description_hash=description_hash
|
amount=amount, memo=invoice_memo, description_hash=description_hash
|
||||||
)
|
)
|
||||||
if not ok:
|
if not ok:
|
||||||
raise Exception(error_message or "Unexpected backend error.")
|
raise InvoiceFailure(error_message or "Unexpected backend error.")
|
||||||
|
|
||||||
invoice = bolt11.decode(payment_request)
|
invoice = bolt11.decode(payment_request)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,13 @@ from lnbits import bolt11
|
||||||
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
||||||
|
|
||||||
from .. import core_app, db
|
from .. import core_app, db
|
||||||
from ..services import PaymentFailure, create_invoice, pay_invoice, perform_lnurlauth
|
from ..services import (
|
||||||
|
PaymentFailure,
|
||||||
|
InvoiceFailure,
|
||||||
|
create_invoice,
|
||||||
|
pay_invoice,
|
||||||
|
perform_lnurlauth,
|
||||||
|
)
|
||||||
from ..tasks import sse_listeners
|
from ..tasks import sse_listeners
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -67,6 +73,7 @@ async def api_payments_create_invoice():
|
||||||
memo = g.data["memo"]
|
memo = g.data["memo"]
|
||||||
|
|
||||||
async with db.connect() as conn:
|
async with db.connect() as conn:
|
||||||
|
try:
|
||||||
payment_hash, payment_request = await create_invoice(
|
payment_hash, payment_request = await create_invoice(
|
||||||
wallet_id=g.wallet.id,
|
wallet_id=g.wallet.id,
|
||||||
amount=g.data["amount"],
|
amount=g.data["amount"],
|
||||||
|
|
@ -76,6 +83,10 @@ async def api_payments_create_invoice():
|
||||||
webhook=g.data.get("webhook"),
|
webhook=g.data.get("webhook"),
|
||||||
conn=conn,
|
conn=conn,
|
||||||
)
|
)
|
||||||
|
except InvoiceFailure as e:
|
||||||
|
return jsonify({"message": str(e)}), 520
|
||||||
|
except Exception as exc:
|
||||||
|
raise exc
|
||||||
|
|
||||||
invoice = bolt11.decode(payment_request)
|
invoice = bolt11.decode(payment_request)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,15 @@ async def api_amilkit(amilk_id):
|
||||||
except LnurlException:
|
except LnurlException:
|
||||||
abort(HTTPStatus.INTERNAL_SERVER_ERROR, "Could not process withdraw LNURL.")
|
abort(HTTPStatus.INTERNAL_SERVER_ERROR, "Could not process withdraw LNURL.")
|
||||||
|
|
||||||
|
try:
|
||||||
payment_hash, payment_request = await create_invoice(
|
payment_hash, payment_request = await create_invoice(
|
||||||
wallet_id=milk.wallet,
|
wallet_id=milk.wallet,
|
||||||
amount=withdraw_res.max_sats,
|
amount=withdraw_res.max_sats,
|
||||||
memo=memo,
|
memo=memo,
|
||||||
extra={"tag": "amilk"},
|
extra={"tag": "amilk"},
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
|
|
||||||
r = httpx.get(
|
r = httpx.get(
|
||||||
withdraw_res.callback.base,
|
withdraw_res.callback.base,
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,13 @@ class BleskomatLnurl(NamedTuple):
|
||||||
raise LnurlValidationError("Maximum number of uses already reached")
|
raise LnurlValidationError("Maximum number of uses already reached")
|
||||||
tag = self.tag
|
tag = self.tag
|
||||||
if tag == "withdrawRequest":
|
if tag == "withdrawRequest":
|
||||||
|
try:
|
||||||
payment_hash = await pay_invoice(
|
payment_hash = await pay_invoice(
|
||||||
wallet_id=self.wallet,
|
wallet_id=self.wallet,
|
||||||
payment_request=query["pr"],
|
payment_request=query["pr"],
|
||||||
)
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
raise LnurlValidationError(f"Failed to pay invoice: {exc.message}")
|
||||||
if not payment_hash:
|
if not payment_hash:
|
||||||
raise LnurlValidationError("Failed to pay invoice")
|
raise LnurlValidationError("Failed to pay invoice")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,12 +116,16 @@ async def api_ticket_make_ticket(form_id):
|
||||||
|
|
||||||
nwords = len(re.split(r"\s+", g.data["ltext"]))
|
nwords = len(re.split(r"\s+", g.data["ltext"]))
|
||||||
sats = g.data["sats"]
|
sats = g.data["sats"]
|
||||||
|
|
||||||
|
try:
|
||||||
payment_hash, payment_request = await create_invoice(
|
payment_hash, payment_request = await create_invoice(
|
||||||
wallet_id=form.wallet,
|
wallet_id=form.wallet,
|
||||||
amount=sats,
|
amount=sats,
|
||||||
memo=f"ticket with {nwords} words on {form_id}",
|
memo=f"ticket with {nwords} words on {form_id}",
|
||||||
extra={"tag": "lnticket"},
|
extra={"tag": "lnticket"},
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
|
|
||||||
ticket = await create_ticket(
|
ticket = await create_ticket(
|
||||||
payment_hash=payment_hash, wallet=form.wallet, **g.data
|
payment_hash=payment_hash, wallet=form.wallet, **g.data
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ async def lnurl_callback(item_id):
|
||||||
)
|
)
|
||||||
|
|
||||||
shop = await get_shop(item.shop)
|
shop = await get_shop(item.shop)
|
||||||
|
|
||||||
|
try:
|
||||||
payment_hash, payment_request = await create_invoice(
|
payment_hash, payment_request = await create_invoice(
|
||||||
wallet_id=shop.wallet,
|
wallet_id=shop.wallet,
|
||||||
amount=int(amount_received / 1000),
|
amount=int(amount_received / 1000),
|
||||||
|
|
@ -73,6 +75,8 @@ async def lnurl_callback(item_id):
|
||||||
).digest(),
|
).digest(),
|
||||||
extra={"tag": "offlineshop", "item": item.id},
|
extra={"tag": "offlineshop", "item": item.id},
|
||||||
)
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
return jsonify(LnurlErrorResponse(reason=exc.message).dict())
|
||||||
|
|
||||||
resp = LnurlPayActionResponse(
|
resp = LnurlPayActionResponse(
|
||||||
pr=payment_request,
|
pr=payment_request,
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
import re
|
|
||||||
from quart import g, jsonify, request
|
from quart import g, jsonify, request
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from lnbits.core import crud
|
|
||||||
import json
|
|
||||||
|
|
||||||
import httpx
|
from lnbits.core.crud import get_user
|
||||||
from lnbits.core.crud import get_user, get_wallet
|
|
||||||
from lnbits.core.services import create_invoice, check_invoice_status
|
from lnbits.core.services import create_invoice, check_invoice_status
|
||||||
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
||||||
|
|
||||||
from .util import isValidDomain, isvalidIPAddress
|
|
||||||
from . import subdomains_ext
|
from . import subdomains_ext
|
||||||
from .crud import (
|
from .crud import (
|
||||||
create_subdomain,
|
create_subdomain,
|
||||||
|
|
@ -169,12 +164,16 @@ async def api_subdomain_make_subdomain(domain_id):
|
||||||
|
|
||||||
## ALL OK - create an invoice and return it to the user
|
## ALL OK - create an invoice and return it to the user
|
||||||
sats = g.data["sats"]
|
sats = g.data["sats"]
|
||||||
|
|
||||||
|
try:
|
||||||
payment_hash, payment_request = await create_invoice(
|
payment_hash, payment_request = await create_invoice(
|
||||||
wallet_id=domain.wallet,
|
wallet_id=domain.wallet,
|
||||||
amount=sats,
|
amount=sats,
|
||||||
memo=f"subdomain {g.data['subdomain']}.{domain.domain} for {sats} sats for {g.data['duration']} days",
|
memo=f"subdomain {g.data['subdomain']}.{domain.domain} for {sats} sats for {g.data['duration']} days",
|
||||||
extra={"tag": "lnsubdomain"},
|
extra={"tag": "lnsubdomain"},
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
|
|
||||||
subdomain = await create_subdomain(
|
subdomain = await create_subdomain(
|
||||||
payment_hash=payment_hash, wallet=domain.wallet, **g.data
|
payment_hash=payment_hash, wallet=domain.wallet, **g.data
|
||||||
|
|
|
||||||
|
|
@ -119,11 +119,10 @@ async def api_lnurl_callback(unique_hash):
|
||||||
|
|
||||||
await update_withdraw_link(link.id, **changes)
|
await update_withdraw_link(link.id, **changes)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return jsonify({"status": "ERROR", "reason": str(e)}), HTTPStatus.OK
|
return jsonify({"status": "ERROR", "reason": str(e)})
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
return (
|
return jsonify({"status": "ERROR", "reason": "Withdraw link is empty."})
|
||||||
jsonify({"status": "ERROR", "reason": "Withdraw link is empty."}),
|
except Exception as e:
|
||||||
HTTPStatus.OK,
|
return jsonify({"status": "ERROR", "reason": str(e)})
|
||||||
)
|
|
||||||
|
|
||||||
return jsonify({"status": "OK"}), HTTPStatus.OK
|
return jsonify({"status": "OK"}), HTTPStatus.OK
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class SparkWallet(Wallet):
|
||||||
timeout=40,
|
timeout=40,
|
||||||
)
|
)
|
||||||
except (OSError, httpx.ConnectError, httpx.RequestError) as exc:
|
except (OSError, httpx.ConnectError, httpx.RequestError) as exc:
|
||||||
raise SparkError("error connecting to spark: " + str(exc))
|
raise UnknownError("error connecting to spark: " + str(exc))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = r.json()
|
data = r.json()
|
||||||
|
|
@ -123,7 +123,7 @@ class SparkWallet(Wallet):
|
||||||
payment_hash = pay["payment_hash"]
|
payment_hash = pay["payment_hash"]
|
||||||
|
|
||||||
if len(pays) > 1:
|
if len(pays) > 1:
|
||||||
raise Exception(
|
raise SparkError(
|
||||||
f"listpays({payment_hash}) returned an unexpected response: {listpays}"
|
f"listpays({payment_hash}) returned an unexpected response: {listpays}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue