Files
yara724api/src/utils/sms-manager/sms-provider.exception.ts
2026-04-06 14:33:33 +03:30

70 lines
1.9 KiB
TypeScript

import { HttpException, HttpStatus } from "@nestjs/common";
import {
KavenegarNormalized,
safeJsonStringify,
unwrapKavenegarTransportError,
} from "./kavenegar-response";
export type SmsOperation = "verifyLookup" | "send";
export class SmsProviderException extends HttpException {
constructor(
public readonly operation: SmsOperation,
public readonly meta: {
receptor: string;
template?: string;
providerBody: unknown;
normalized: KavenegarNormalized;
},
) {
super(
"SMS delivery could not be confirmed by the provider.",
HttpStatus.BAD_GATEWAY,
);
}
}
export class SmsTransportException extends HttpException {
constructor(
public readonly operation: SmsOperation,
public readonly meta: { receptor: string; template?: string },
public readonly causeUnknown: unknown,
) {
super(
"SMS service failed before a provider response was received.",
HttpStatus.BAD_GATEWAY,
);
}
}
/** Single-line detail for logs (provider vs transport vs unexpected). */
export function describeSmsError(err: unknown): string {
if (err instanceof SmsProviderException) {
const n = err.meta.normalized;
return [
`SmsProviderException(${err.operation})`,
`receptor=${err.meta.receptor}`,
err.meta.template ? `template=${err.meta.template}` : "",
`providerStatus=${n.httpLikeStatus ?? "unknown"}`,
`providerMessage=${n.message ?? "n/a"}`,
`body=${n.raw}`,
]
.filter(Boolean)
.join(" ");
}
if (err instanceof SmsTransportException) {
return [
`SmsTransportException(${err.operation})`,
`receptor=${err.meta.receptor}`,
err.meta.template ? `template=${err.meta.template}` : "",
`detail=${safeJsonStringify(unwrapKavenegarTransportError(err.causeUnknown))}`,
]
.filter(Boolean)
.join(" ");
}
if (err instanceof Error) {
return `${err.name}: ${err.message}`;
}
return safeJsonStringify(err);
}