mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-07 18:56:36 +02:00
feat: catch wallet init exception, string formatting (#1846)
this catches exception on set_wallet_class and switches to VoidWallet if it fails
This commit is contained in:
@@ -64,7 +64,10 @@ def create_app() -> FastAPI:
|
|||||||
configure_logger()
|
configure_logger()
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title="LNbits API",
|
title="LNbits API",
|
||||||
description="API for LNbits, the free and open source bitcoin wallet and accounts system with plugins.",
|
description=(
|
||||||
|
"API for LNbits, the free and open source bitcoin wallet and "
|
||||||
|
"accounts system with plugins."
|
||||||
|
),
|
||||||
version=settings.version,
|
version=settings.version,
|
||||||
license_info={
|
license_info={
|
||||||
"name": "MIT License",
|
"name": "MIT License",
|
||||||
@@ -108,7 +111,9 @@ async def check_funding_source() -> None:
|
|||||||
original_sigint_handler = signal.getsignal(signal.SIGINT)
|
original_sigint_handler = signal.getsignal(signal.SIGINT)
|
||||||
|
|
||||||
def signal_handler(signal, frame):
|
def signal_handler(signal, frame):
|
||||||
logger.debug("SIGINT received, terminating LNbits.")
|
logger.debug(
|
||||||
|
f"SIGINT received, terminating LNbits. signal: {signal}, frame: {frame}"
|
||||||
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
@@ -130,17 +135,15 @@ async def check_funding_source() -> None:
|
|||||||
break
|
break
|
||||||
|
|
||||||
logger.error(
|
logger.error(
|
||||||
f"The backend for {WALLET.__class__.__name__} isn't working properly: '{error_message}'",
|
f"The backend for {WALLET.__class__.__name__} isn't "
|
||||||
|
f"working properly: '{error_message}'",
|
||||||
RuntimeWarning,
|
RuntimeWarning,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if settings.lnbits_admin_ui and retry_counter == timeout:
|
if settings.lnbits_admin_ui and retry_counter == timeout:
|
||||||
logger.warning(
|
set_void_wallet_class()
|
||||||
f"Fallback to VoidWallet, because the backend for {WALLET.__class__.__name__} isn't working properly"
|
|
||||||
)
|
|
||||||
set_wallet_class("VoidWallet")
|
|
||||||
WALLET = get_wallet_class()
|
WALLET = get_wallet_class()
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -151,16 +154,25 @@ async def check_funding_source() -> None:
|
|||||||
signal.signal(signal.SIGINT, original_sigint_handler)
|
signal.signal(signal.SIGINT, original_sigint_handler)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"✔️ Backend {WALLET.__class__.__name__} connected and with a balance of {balance} msat."
|
f"✔️ Backend {WALLET.__class__.__name__} connected "
|
||||||
|
f"and with a balance of {balance} msat."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def set_void_wallet_class():
|
||||||
|
logger.warning(
|
||||||
|
"Fallback to VoidWallet, because the backend for "
|
||||||
|
f"{settings.lnbits_backend_wallet_class} isn't working properly"
|
||||||
|
)
|
||||||
|
set_wallet_class("VoidWallet")
|
||||||
|
|
||||||
|
|
||||||
async def check_installed_extensions(app: FastAPI):
|
async def check_installed_extensions(app: FastAPI):
|
||||||
"""
|
"""
|
||||||
Check extensions that have been installed, but for some reason no longer present in the 'lnbits/extensions' directory.
|
Check extensions that have been installed, but for some reason no longer present in
|
||||||
One reason might be a docker-container that was re-created.
|
the 'lnbits/extensions' directory. One reason might be a docker-container that was
|
||||||
The 'data' directory (where the '.zip' files live) is expected to persist state.
|
re-created. The 'data' directory (where the '.zip' files live) is expected to
|
||||||
Zips that are missing will be re-downloaded.
|
persist state. Zips that are missing will be re-downloaded.
|
||||||
"""
|
"""
|
||||||
shutil.rmtree(os.path.join("lnbits", "upgrades"), True)
|
shutil.rmtree(os.path.join("lnbits", "upgrades"), True)
|
||||||
await load_disabled_extension_list()
|
await load_disabled_extension_list()
|
||||||
@@ -172,7 +184,8 @@ async def check_installed_extensions(app: FastAPI):
|
|||||||
if not installed:
|
if not installed:
|
||||||
await restore_installed_extension(app, ext)
|
await restore_installed_extension(app, ext)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"✔️ Successfully re-installed extension: {ext.id} ({ext.installed_version})"
|
"✔️ Successfully re-installed extension: "
|
||||||
|
f"{ext.id} ({ext.installed_version})"
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(e)
|
logger.warning(e)
|
||||||
@@ -257,7 +270,8 @@ def register_routes(app: FastAPI) -> None:
|
|||||||
|
|
||||||
def register_new_ext_routes(app: FastAPI) -> Callable:
|
def register_new_ext_routes(app: FastAPI) -> Callable:
|
||||||
# Returns a function that registers new routes for an extension.
|
# Returns a function that registers new routes for an extension.
|
||||||
# The returned function encapsulates (creates a closure around) the `app` object but does expose it.
|
# The returned function encapsulates (creates a closure around)
|
||||||
|
# the `app` object but does expose it.
|
||||||
def register_new_ext_routes_fn(ext: Extension):
|
def register_new_ext_routes_fn(ext: Extension):
|
||||||
register_ext_routes(app, ext)
|
register_ext_routes(app, ext)
|
||||||
|
|
||||||
@@ -324,7 +338,14 @@ def register_startup(app: FastAPI):
|
|||||||
add_ip_block_middleware(app)
|
add_ip_block_middleware(app)
|
||||||
|
|
||||||
# initialize WALLET
|
# initialize WALLET
|
||||||
set_wallet_class()
|
try:
|
||||||
|
set_wallet_class()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(
|
||||||
|
f"Error initializing {settings.lnbits_backend_wallet_class}: "
|
||||||
|
f"{str(e)}"
|
||||||
|
)
|
||||||
|
set_void_wallet_class()
|
||||||
|
|
||||||
# initialize funding source
|
# initialize funding source
|
||||||
await check_funding_source()
|
await check_funding_source()
|
||||||
@@ -500,11 +521,16 @@ def configure_logger() -> None:
|
|||||||
class Formatter:
|
class Formatter:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.padding = 0
|
self.padding = 0
|
||||||
self.minimal_fmt: str = "<green>{time:YYYY-MM-DD HH:mm:ss.SS}</green> | <level>{level}</level> | <level>{message}</level>\n"
|
self.minimal_fmt: str = (
|
||||||
|
"<green>{time:YYYY-MM-DD HH:mm:ss.SS}</green> | <level>{level}</level> | "
|
||||||
|
"<level>{message}</level>\n"
|
||||||
|
)
|
||||||
if settings.debug:
|
if settings.debug:
|
||||||
self.fmt: str = (
|
self.fmt: str = (
|
||||||
"<green>{time:YYYY-MM-DD HH:mm:ss.SS}</green> | <level>{level: <4}</level> | "
|
"<green>{time:YYYY-MM-DD HH:mm:ss.SS}</green> | "
|
||||||
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | <level>{message}</level>\n"
|
"<level>{level: <4}</level> | "
|
||||||
|
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | "
|
||||||
|
"<level>{message}</level>\n"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.fmt: str = self.minimal_fmt
|
self.fmt: str = self.minimal_fmt
|
||||||
|
Reference in New Issue
Block a user