Swift y Objective-C

Definir mensajes de error personalizados en Swift y dominar LocalizedError (con ejemplos)

Al crear una app con Swift, es posible que hayas capturado un error con do-catch y luego te hayas encontrado con que el mensaje mostrado en pantalla no era nada útil.

3 min de lectura
Imagen de portada de Definir mensajes de error personalizados en Swift y dominar LocalizedError (con ejemplos)

Al crear una app con Swift, es posible que hayas capturado un error con do-catch y luego te hayas encontrado con que el mensaje mostrado en pantalla no era nada útil.

Si usas error.localizedDescription tal cual, es fácil que el usuario vea directamente mensajes enigmáticos como “The operation couldn’t be completed…”.

Empecemos por la conclusión.

Para definir mensajes de error personalizados que se muestren al usuario en Swift, adopta el protocolo LocalizedError en lugar de Error e implementa la propiedad errorDescription.

Hoy veremos este método paso a paso, con ejemplos.


¿Por qué Error no es suficiente?

Muchas personas definirían el error de esta manera.

enum LoginError: Error {
    case invalidPassword
    case userNotFound
}

Si solo haces esto y muestras error.localizedDescription, no aparecerá el esperado “La contraseña es incorrecta”, sino el mensaje predeterminado y poco informativo generado por el sistema.

Esto ocurre porque el propio protocolo Error no ofrece un lugar para definir un mensaje legible para las personas.

Ahí es donde entra LocalizedError.


¿Cómo se definen los mensajes de error personalizados en Swift?

Es sencillo: adopta LocalizedError e implementa errorDescription.

Este es un ejemplo que añade mensajes para el usuario a errores de inicio de sesión.

extension LoginError: LocalizedError {
    var errorDescription: String? {
        switch self {
        case .invalidPassword:
            return "La contraseña no es correcta."
        case .userNotFound:
            return "El usuario no existe."
        }
    }
}

Ahora, al llamar a error.localizedDescription, aparecerá exactamente el mensaje que definimos.

El punto clave es que el tipo de retorno de errorDescription es String?, es decir, un opcional.

Si devuelves nil aquí, volverás al mensaje predeterminado del sistema. Por eso es importante proporcionar un valor para todos los casos.

La clave es proporcionar una cadena para cada caso
La clave es proporcionar una cadena para cada caso

¿Hay algo más aparte de errorDescription? (failureReason y recoverySuggestion)

Sí, LocalizedError también incluye otras propiedades que puedes implementar de forma opcional.

Sus funciones se resumen en esta tabla.

Propiedad Función Mensaje de ejemplo
errorDescription Qué salió mal “El inicio de sesión falló.”
failureReason Por qué ocurrió “La contraseña se introdujo incorrectamente 5 veces.”
recoverySuggestion Cómo solucionarlo “Inténtalo de nuevo más tarde.”

En particular, recoverySuggestion resulta útil para indicar al usuario cuál debe ser su siguiente acción.

De hecho, en SwiftUI, Alert y los entornos AppKit pueden leer estos valores automáticamente y colocarlos en pantalla.

En los errores destinados a los usuarios, suelo asegurarme de incluir al menos errorDescription y recoverySuggestion.


No confundas los registros de desarrollo con los mensajes para el usuario

Permíteme añadir un último punto.

Te recomiendo separar la explicación para desarrolladores que quieres registrar durante la depuración como CustomStringConvertible (es decir, description),

y el mensaje traducido que verá el usuario como LocalizedError.

Sus objetivos son diferentes: uno es para mí y el otro, para el usuario.

Al separar así estas responsabilidades, también resulta mucho más sencillo añadir NSLocalizedString cuando necesites admitir varios idiomas.


En una línea: “Si es un error que verá el usuario, empecemos por completar errorDescription de LocalizedError”.

Un pequeño hábito puede cambiar por completo la experiencia del usuario, así que pruébalo en tu próximo proyecto. ¡Ánimo! 🙌


Material de referencia

Lecturas recomendadas