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
|
||||
|
||||
|
||||
class InvoiceFailure(Exception):
|
||||
pass
|
||||
|
||||
|
||||
async def create_invoice(
|
||||
*,
|
||||
wallet_id: str,
|
||||
|
|
@ -50,7 +54,7 @@ async def create_invoice(
|
|||
amount=amount, memo=invoice_memo, description_hash=description_hash
|
||||
)
|
||||
if not ok:
|
||||
raise Exception(error_message or "Unexpected backend error.")
|
||||
raise InvoiceFailure(error_message or "Unexpected backend error.")
|
||||
|
||||
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 .. 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
|
||||
|
||||
|
||||
|
|
@ -67,6 +73,7 @@ async def api_payments_create_invoice():
|
|||
memo = g.data["memo"]
|
||||
|
||||
async with db.connect() as conn:
|
||||
try:
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
wallet_id=g.wallet.id,
|
||||
amount=g.data["amount"],
|
||||
|
|
@ -76,6 +83,10 @@ async def api_payments_create_invoice():
|
|||
webhook=g.data.get("webhook"),
|
||||
conn=conn,
|
||||
)
|
||||
except InvoiceFailure as e:
|
||||
return jsonify({"message": str(e)}), 520
|
||||
except Exception as exc:
|
||||
raise exc
|
||||
|
||||
invoice = bolt11.decode(payment_request)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,12 +37,15 @@ async def api_amilkit(amilk_id):
|
|||
except LnurlException:
|
||||
abort(HTTPStatus.INTERNAL_SERVER_ERROR, "Could not process withdraw LNURL.")
|
||||
|
||||
try:
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
wallet_id=milk.wallet,
|
||||
amount=withdraw_res.max_sats,
|
||||
memo=memo,
|
||||
extra={"tag": "amilk"},
|
||||
)
|
||||
except Exception as e:
|
||||
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
|
||||
r = httpx.get(
|
||||
withdraw_res.callback.base,
|
||||
|
|
|
|||
|
|
@ -86,10 +86,13 @@ class BleskomatLnurl(NamedTuple):
|
|||
raise LnurlValidationError("Maximum number of uses already reached")
|
||||
tag = self.tag
|
||||
if tag == "withdrawRequest":
|
||||
try:
|
||||
payment_hash = await pay_invoice(
|
||||
wallet_id=self.wallet,
|
||||
payment_request=query["pr"],
|
||||
)
|
||||
except Exception as exc:
|
||||
raise LnurlValidationError(f"Failed to pay invoice: {exc.message}")
|
||||
if not payment_hash:
|
||||
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"]))
|
||||
sats = g.data["sats"]
|
||||
|
||||
try:
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
wallet_id=form.wallet,
|
||||
amount=sats,
|
||||
memo=f"ticket with {nwords} words on {form_id}",
|
||||
extra={"tag": "lnticket"},
|
||||
)
|
||||
except Exception as e:
|
||||
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
|
||||
ticket = await create_ticket(
|
||||
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)
|
||||
|
||||
try:
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
wallet_id=shop.wallet,
|
||||
amount=int(amount_received / 1000),
|
||||
|
|
@ -73,6 +75,8 @@ async def lnurl_callback(item_id):
|
|||
).digest(),
|
||||
extra={"tag": "offlineshop", "item": item.id},
|
||||
)
|
||||
except Exception as exc:
|
||||
return jsonify(LnurlErrorResponse(reason=exc.message).dict())
|
||||
|
||||
resp = LnurlPayActionResponse(
|
||||
pr=payment_request,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
import re
|
||||
from quart import g, jsonify, request
|
||||
from http import HTTPStatus
|
||||
from lnbits.core import crud
|
||||
import json
|
||||
|
||||
import httpx
|
||||
from lnbits.core.crud import get_user, get_wallet
|
||||
from lnbits.core.crud import get_user
|
||||
from lnbits.core.services import create_invoice, check_invoice_status
|
||||
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
||||
|
||||
from .util import isValidDomain, isvalidIPAddress
|
||||
from . import subdomains_ext
|
||||
from .crud import (
|
||||
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
|
||||
sats = g.data["sats"]
|
||||
|
||||
try:
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
wallet_id=domain.wallet,
|
||||
amount=sats,
|
||||
memo=f"subdomain {g.data['subdomain']}.{domain.domain} for {sats} sats for {g.data['duration']} days",
|
||||
extra={"tag": "lnsubdomain"},
|
||||
)
|
||||
except Exception as e:
|
||||
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
|
||||
subdomain = await create_subdomain(
|
||||
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)
|
||||
except ValueError as e:
|
||||
return jsonify({"status": "ERROR", "reason": str(e)}), HTTPStatus.OK
|
||||
return jsonify({"status": "ERROR", "reason": str(e)})
|
||||
except PermissionError:
|
||||
return (
|
||||
jsonify({"status": "ERROR", "reason": "Withdraw link is empty."}),
|
||||
HTTPStatus.OK,
|
||||
)
|
||||
return jsonify({"status": "ERROR", "reason": "Withdraw link is empty."})
|
||||
except Exception as e:
|
||||
return jsonify({"status": "ERROR", "reason": str(e)})
|
||||
|
||||
return jsonify({"status": "OK"}), HTTPStatus.OK
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class SparkWallet(Wallet):
|
|||
timeout=40,
|
||||
)
|
||||
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:
|
||||
data = r.json()
|
||||
|
|
@ -123,7 +123,7 @@ class SparkWallet(Wallet):
|
|||
payment_hash = pay["payment_hash"]
|
||||
|
||||
if len(pays) > 1:
|
||||
raise Exception(
|
||||
raise SparkError(
|
||||
f"listpays({payment_hash}) returned an unexpected response: {listpays}"
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue