import { log } from '@any-ui/core' import { FORM_ERROR, SubmissionErrors } from 'final-form' const firebaseHttpsCodeMessageMap: Partial> = { 'already-exists': 'Already exists', 'failed-precondition': 'Invalid', } let unexpectedFormErrorMessage = 'Apologies, request failed' export const setUnexpectedFormErrorMessage = (message: string) => { unexpectedFormErrorMessage = message } export const globalFormError = (e: any): SubmissionErrors => { if (typeof e === 'string') { return { [FORM_ERROR]: e } } return { [FORM_ERROR]: unexpectedFormErrorMessage } } export const fieldError = ( field: keyof T, message: string ): SubmissionErrors => ({ [field]: message }) export interface IFirebaseHttpsError extends Error { /** * A standard error code that will be returned to the client. This also * determines the HTTP status code of the response, as defined in code.proto. */ readonly code: string /** * Extra data to be converted to JSON and included in the error response. */ readonly details?: any } export type ErrorHandler = (e: any) => void let unexpectedErrorHandler: ErrorHandler | null = null export const onUnexpectedFormError = (handler: ErrorHandler | null) => { unexpectedErrorHandler = handler } export const handleUnexpectedError = (e: any): SubmissionErrors => { log.error(e) if (unexpectedErrorHandler) { unexpectedErrorHandler(e) } return globalFormError(e) } export const httpsToSubmissionErrorAdapter = ( e: IFirebaseHttpsError ): SubmissionErrors => { if (typeof e.details === 'string' && e.code in firebaseHttpsCodeMessageMap) { // log.error(e); return fieldError(e.details, firebaseHttpsCodeMessageMap[e.code]!) } return handleUnexpectedError(e) } export const mapValidationErrors = ( e: any, errorCodeMapField: Record ): SubmissionErrors => { const errorCode = e && e.code if (errorCode && errorCode in errorCodeMapField) { const field = errorCodeMapField[errorCode] // log.error(e); return fieldError(field, e.message) } return handleUnexpectedError(e) }