Menu
Coddy logo textTech

Resumen - Analizador de archivos

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy. Lección 58 de 107.

challenge icon

Desafío

Fácil

Construyamos un analizador de archivos de configuración que reúna todas las técnicas de manejo de errores de este capítulo. Tu analizador gestionará varios escenarios de fallo con tipos de error personalizados, errores centinela, envoltorio de errores y una limpieza adecuada mediante defer.

Organizarás tu código en tres archivos:

  • errors.go: Define la infraestructura de errores para el analizador.

    Crea dos errores centinela:

    • ErrEmptyContent con el mensaje "file content is empty"
    • ErrInvalidFormat con el mensaje "invalid configuration format"

    Crea un tipo de error personalizado ParseError con los campos Line (int) y Message (string). Su método Error() debe devolver: parse error at line [Line]: [Message]

  • parser.go: Construye el analizador de configuración con manejo de errores por capas.

    Crea una estructura ConfigParser con un campo booleano parsed para realizar un seguimiento de si el análisis se completó correctamente.

    Implementa estos métodos:

    • NewConfigParser() *ConfigParser - crea un analizador nuevo con parsed establecido en false
    • ParseLine(lineNum int, line string) error - valida una sola línea. Si la línea no contiene un carácter =, devuelve un *ParseError con el número de línea y el mensaje "missing key-value separator". De lo contrario, devuelve nil.
    • Parse(content string) error - el método principal de análisis que:
      • Devuelve ErrEmptyContent si el contenido está vacío
      • Devuelve ErrInvalidFormat si el contenido no contiene al menos un carácter de nueva línea
      • Divide el contenido por las nuevas líneas y llama a ParseLine para cada línea (los números de línea comienzan en 1)
      • Si ParseLine devuelve un error, lo envuelve con "parsing configuration: %w" y lo devuelve
      • Establece parsed en true si todo tiene éxito y devuelve nil
    • Status() string - devuelve "ready" si parsed es true; de lo contrario, devuelve "not parsed"
  • main.go: Lee el contenido de la configuración y muestra una inspección completa de los errores.

    Lee dos líneas de entrada que juntas forman el contenido de la configuración (únelas con una nueva línea). Usa defer para imprimir siempre el estado del analizador al final, independientemente de que la operación tenga éxito o falle.

    Después de intentar analizar el contenido, inspecciona cualquier error usando tanto errors.Is() como errors.As() para proporcionar información específica según lo ocurrido.

Se proporcionarán las siguientes entradas:

  • Línea 1: Primera línea del contenido de la configuración
  • Línea 2: Segunda línea del contenido de la configuración

Maneja los errores con mensajes específicos:

  • Si errors.Is() encuentra ErrEmptyContent: imprime Error: No configuration provided
  • Si errors.Is() encuentra ErrInvalidFormat: imprime Error: Configuration must have multiple lines
  • Si errors.As() encuentra un *ParseError: imprime el error envuelto completo y, después, en una nueva línea imprime Fix line [Line]: [Message]
  • Si el análisis tiene éxito: imprime Configuration parsed successfully

Después de gestionar el resultado (éxito o error), el estado diferido debe imprimirse en una nueva línea: Parser status: [status]

Por ejemplo, dados host=localhost y port=8080, la salida debe ser:

Configuration parsed successfully
Parser status: ready

Y dados host=localhost y invalid line, la salida debe ser:

parsing configuration: parse error at line 2: missing key-value separator
Fix line 2: missing key-value separator
Parser status: not parsed

Pruébalo tú mismo

package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	
	// Leer la primera línea de configuración
	line1, _ := reader.ReadString('\n')
	line1 = line1[:len(line1)-1] // Eliminar el salto de línea final
	
	// Leer la segunda línea de configuración
	line2, _ := reader.ReadString('\n')
	if len(line2) > 0 && line2[len(line2)-1] == '\n' {
		line2 = line2[:len(line2)-1]
	}
	
	// Unir las dos líneas con un salto de línea para formar el contenido de la configuración
	content := line1 + "\n" + line2
	
	// Crear un nuevo analizador (parser)
	parser := NewConfigParser()
	
	// TODO: Usar defer para imprimir siempre el estado del analizador al final
	// Formato: "Parser status: [status]"
	
	// TODO: Intentar analizar el contenido
	
	// TODO: Manejar errores usando errors.Is() y errors.As()
	// - Si errors.Is() encuentra ErrEmptyContent: imprimir "Error: No configuration provided"
	// - Si errors.Is() encuentra ErrInvalidFormat: imprimir "Error: Configuration must have multiple lines"
	// - Si errors.As() encuentra un *ParseError: imprimir el error envuelto completo,
	//   luego en una nueva línea imprimir "Fix line [Line]: [Message]"
	// - Si el análisis tiene éxito: imprimir "Configuration parsed successfully"
	
	_ = errors.Is // pista: usar errors.Is para errores centinela
	_ = errors.As // pista: usar errors.As para tipos de error personalizados
	_ = fmt.Println
}

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Go online