Coverage for functions \ flipdare \ error \ app_stripe_error.py: 90%
31 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
1#!/usr/bin/env python
2# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved.
3#
4# This file is part of Flipdare's proprietary software and contains
5# confidential and copyrighted material. Unauthorised copying,
6# modification, distribution, or use of this file is strictly
7# prohibited without prior written permission from Flipdare Pty Ltd.
8#
9# This software includes third-party components licensed under MIT,
10# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details.
11#
14from typing import Self, override
15from flipdare.error.app_error import AppError
16from flipdare.error.app_error_protocol import AppErrorProtocol, ErrorProtocolGuard
17from flipdare.error.error_context import ErrorContext
18from flipdare.error.stripe_error_context import StripeErrorContext
19from flipdare.generated.shared.app_payment_error_code import AppPaymentErrorCode
20from flipdare.message.error_message import ErrorMessage
21from flipdare.message.user_error_code import UserStripeErrorCode
22from flipdare.payments.payment_types import KnownStripeErrorType
24__all__ = ["AppStripeError"]
27# NOTE: its not necessary to pass around stripe_error_code,
28# NOTE: its inserted into the message if exists.
31class AppStripeError(AppError):
32 def __init__(
33 self,
34 endpoint: str,
35 message: str | None = None,
36 error_code: AppErrorProtocol = AppPaymentErrorCode.UNKNOWN_ERROR,
37 cause: str | None = None,
38 error: Exception | None = None,
39 ) -> None:
40 if message is None and ErrorProtocolGuard.is_payment_code(error_code):
41 error_msg = ErrorMessage.for_payment(error_code)
42 if error_msg is not None:
43 message = error_msg.formatted_payment_error()
45 if message is None:
46 message = ErrorMessage.UNKNOWN_ERROR.formatted_payment_error()
48 super().__init__(
49 source=endpoint,
50 error_code=error_code,
51 message=message,
52 cause=cause,
53 error=error,
54 )
56 @classmethod
57 def from_error(cls, endpoint: str, cause: str | None, error: KnownStripeErrorType) -> Self:
58 error_data = StripeErrorContext.from_stripe_error(
59 endpoint=endpoint,
60 cause=cause,
61 error=error,
62 )
63 return cls(
64 endpoint=error_data.endpoint,
65 error_code=error_data.error_code,
66 message=error_data.message,
67 cause=error_data.cause,
68 error=error,
69 )
71 @classmethod
72 def invalid_data(
73 cls,
74 endpoint: str,
75 invalid_error_code: UserStripeErrorCode,
76 cause: str | None = None,
77 ) -> Self:
78 msg = ErrorMessage.STR_INVALID_API_RESPONSE.message.format(INVALID_CODE=invalid_error_code)
79 return cls(
80 endpoint=endpoint,
81 error_code=AppPaymentErrorCode.INVALID_API_RESPONSE,
82 message=msg,
83 cause=cause,
84 )
86 @classmethod
87 @override
88 def from_context(cls, ctx: ErrorContext) -> Self:
89 return cls(
90 endpoint=ctx.endpoint,
91 error_code=ctx.error_code,
92 message=ctx.message,
93 cause=ctx.cause,
94 error=ctx.error,
95 )