Catch all exceptions in wallet API (#220)

* Catch all exceptions in wallet API

* Use middleware instead of route class to catch exceptions

* Wallet API: simplify load_mint
This commit is contained in:
sihamon
2023-05-22 21:06:31 +02:00
committed by GitHub
parent 08ceeda36f
commit 5df0a9aa59
2 changed files with 33 additions and 65 deletions

View File

@@ -1,4 +1,5 @@
from fastapi import FastAPI from fastapi import FastAPI, Request, status
from fastapi.responses import JSONResponse
from ...core.settings import settings from ...core.settings import settings
from .router import router from .router import router
@@ -19,4 +20,16 @@ def create_app() -> FastAPI:
app = create_app() app = create_app()
@app.middleware("http")
async def catch_exceptions(request: Request, call_next):
try:
response = await call_next(request)
return response
except Exception as e:
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST, content={"detail": str(e)}
)
app.include_router(router=router) app.include_router(router=router)

View File

@@ -6,7 +6,7 @@ from os import listdir
from os.path import isdir, join from os.path import isdir, join
from typing import Optional from typing import Optional
from fastapi import APIRouter, HTTPException, Query, status from fastapi import APIRouter, Query
from ...core.base import TokenV3 from ...core.base import TokenV3
from ...core.helpers import sum_proofs from ...core.helpers import sum_proofs
@@ -43,10 +43,7 @@ def create_wallet(url=settings.mint_url, dir=settings.cashu_dir, name="wallet"):
async def load_mint(wallet: Wallet, mint: Optional[str] = None): async def load_mint(wallet: Wallet, mint: Optional[str] = None):
if mint: if mint:
wallet = create_wallet(mint) wallet = create_wallet(mint)
try: await wallet.load_mint()
await wallet.load_mint()
except Exception as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
return wallet return wallet
@@ -56,9 +53,7 @@ wallet = create_wallet()
@router.on_event("startup") @router.on_event("startup")
async def start_wallet(): async def start_wallet():
if settings.tor and not TorProxy().check_platform(): if settings.tor and not TorProxy().check_platform():
raise HTTPException( raise Exception("tor not working.")
status_code=status.HTTP_400_BAD_REQUEST, detail="tor not working"
)
await init_wallet(wallet) await init_wallet(wallet)
@@ -71,23 +66,16 @@ async def pay(
), ),
): ):
if not settings.lightning: if not settings.lightning:
raise HTTPException( raise Exception("lightning not enabled.")
status_code=status.HTTP_400_BAD_REQUEST, detail="lightning not enabled."
)
global wallet global wallet
wallet = await load_mint(wallet, mint) wallet = await load_mint(wallet, mint)
await wallet.load_proofs() await wallet.load_proofs()
initial_balance = wallet.available_balance initial_balance = wallet.available_balance
total_amount, fee_reserve_sat = await wallet.get_pay_amount_with_fees(invoice) total_amount, fee_reserve_sat = await wallet.get_pay_amount_with_fees(invoice)
assert total_amount > 0, HTTPException( assert total_amount > 0, "amount has to be larger than zero."
status_code=status.HTTP_400_BAD_REQUEST, assert wallet.available_balance >= total_amount, "balance is too low."
detail="amount has to be larger than zero.",
)
if wallet.available_balance < total_amount:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="balance is too low."
)
_, send_proofs = await wallet.split_to_send(wallet.proofs, total_amount) _, send_proofs = await wallet.split_to_send(wallet.proofs, total_amount)
await wallet.pay_lightning(send_proofs, invoice) await wallet.pay_lightning(send_proofs, invoice)
await wallet.load_proofs() await wallet.load_proofs()
@@ -169,16 +157,10 @@ async def send_command(
await wallet.load_proofs() await wallet.load_proofs()
if not nostr: if not nostr:
try: balance, token = await send(wallet, amount, lock, legacy=False)
balance, token = await send(wallet, amount, lock, legacy=False)
except Exception as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
return SendResponse(balance=balance, token=token) return SendResponse(balance=balance, token=token)
else: else:
try: token, pubkey = await send_nostr(wallet, amount, nostr)
token, pubkey = await send_nostr(wallet, amount, nostr)
except Exception as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
return SendResponse(balance=wallet.available_balance, token=token, npub=pubkey) return SendResponse(balance=wallet.available_balance, token=token, npub=pubkey)
@@ -191,25 +173,12 @@ async def receive_command(
): ):
initial_balance = wallet.available_balance initial_balance = wallet.available_balance
if token: if token:
try: tokenObj: TokenV3 = await deserialize_token_from_string(token)
tokenObj: TokenV3 = await deserialize_token_from_string(token) await verify_mints(wallet, tokenObj)
balance = await receive(wallet, tokenObj, lock)
try:
await verify_mints(wallet, tokenObj)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)
)
balance = await receive(wallet, tokenObj, lock)
except Exception as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
elif nostr: elif nostr:
try: await receive_nostr(wallet)
await receive_nostr(wallet) balance = wallet.available_balance
balance = wallet.available_balance
except Exception as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
elif all: elif all:
reserved_proofs = await get_reserved_proofs(wallet.db) reserved_proofs = await get_reserved_proofs(wallet.db)
balance = None balance = None
@@ -218,23 +187,10 @@ async def receive_command(
proofs = list(value) proofs = list(value)
token = await wallet.serialize_proofs(proofs) token = await wallet.serialize_proofs(proofs)
tokenObj = await deserialize_token_from_string(token) tokenObj = await deserialize_token_from_string(token)
try: await verify_mints(wallet, tokenObj)
await verify_mints(wallet, tokenObj) balance = await receive(wallet, tokenObj, lock)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)
)
try:
balance = await receive(wallet, tokenObj, lock)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)
)
else: else:
raise HTTPException( raise Exception("enter token or use either flag --nostr or --all.")
status_code=status.HTTP_400_BAD_REQUEST,
detail="enter token or use either flag --nostr or --all.",
)
assert balance assert balance
return ReceiveResponse(initial_balance=initial_balance, balance=balance) return ReceiveResponse(initial_balance=initial_balance, balance=balance)
@@ -257,9 +213,8 @@ async def burn(
if not delete: if not delete:
wallet = await load_mint(wallet, mint) wallet = await load_mint(wallet, mint)
if not (all or token or force or delete) or (token and all): if not (all or token or force or delete) or (token and all):
raise HTTPException( raise Exception(
status_code=status.HTTP_400_BAD_REQUEST, "enter a token or use --all to burn all pending tokens, --force to check all tokens"
detail="enter a token or use --all to burn all pending tokens, --force to check all tokens"
"or --delete with send ID to force-delete pending token from list if mint is unavailable.", "or --delete with send ID to force-delete pending token from list if mint is unavailable.",
) )
if all: if all: