Apariencia
Enumerar errores y razones
Las tres enumeraciones pertenecen a Greencore.Platform.Errors.Extensions.
| Método | Tipo permitido | Incluye la raíz | Filtro predeterminado |
|---|---|---|---|
ErrorsOfType<T>(bool includeNonTerminal = false) | T : Error | Sí, si coincide | Solo hojas |
ReasonsOfType<T>(bool includeNonTerminal = false) | T : class, INode | No | Solo hojas |
NodesOfType<T>(bool includeNonTerminal = false) | T : class, INode | Sí, si coincide | Solo hojas |
Una hoja es un nodo sin hijos. Ser hoja no depende de si el nodo es un error o una razón.
Comparar hojas y todos los niveles
csharp
using System;
using System.Linq;
using Greencore.Platform.Errors;
using Greencore.Platform.Errors.Extensions;
using Greencore.Platform.Nodes;
var error = Error.Create("Importación fallida.")
.WithReason(new Reason("Fila inválida.")
.WithReason(new Reason("Nombre obligatorio."))
.WithReason(new Reason("Correo inválido.")))
.WithReason("Archivo incompleto.");
Console.WriteLine(error.ErrorsOfType<Error>().Count()); // 0.
Console.WriteLine(error.ErrorsOfType<Error>(true).Count()); // 1.
Console.WriteLine(error.ReasonsOfType<IReasonNode>().Count()); // 3.
Console.WriteLine(error.ReasonsOfType<IReasonNode>(true).Count()); // 4.
Console.WriteLine(error.NodesOfType<INode>().Count()); // 3.
Console.WriteLine(error.NodesOfType<INode>(true).Count()); // 5.
foreach (var hoja in error.ReasonsOfType<IReasonNode>())
Console.WriteLine(hoja.Message);Salida del recorrido de hojas:
text
Nombre obligatorio.
Correo inválido.
Archivo incompleto.La raíz tiene razones, por eso ErrorsOfType<Error>() está vacío. Esto no significa que el diagnóstico carezca de error: HasError<Error>() sigue siendo verdadero.
Si la raíz no tiene hijos, ErrorsOfType<Error>() y NodesOfType<INode>() la devuelven, mientras que ReasonsOfType<INode>() está vacío.
Filtrar y materializar
csharp
var todas = error.ReasonsOfType<IReasonNode>(includeNonTerminal: true);
var conMetadatos = todas.Where(razon => razon.Metadata.Count > 0).ToArray();
var mensajes = todas.Select(razon => (string)razon.Message).ToArray();Son secuencias diferidas: el árbol se recorre al consumirlas. ToArray() o ToList() evita repetir el recorrido y captura las referencias encontradas en ese momento; no clona los nodos ni sus metadatos. No modifiques la estructura durante la enumeración ni asumas que proporciona una instantánea segura frente a escrituras concurrentes.
Referencias compartidas
Los recorridos siguen las relaciones Reasons y conservan las apariciones por ruta. Una misma instancia compartida puede aparecer varias veces. Si tu operación necesita instancias únicas:
csharp
var unicos = error.NodesOfType<INode>(includeNonTerminal: true)
.Distinct(System.Collections.Generic.ReferenceEqualityComparer.Instance)
.ToArray();Eliminar duplicados pierde información sobre las distintas rutas. Para mostrar el contexto de cada aparición utiliza EnumerateLeafPaths.
Consultar todos los errores de un agregado
csharp
var primero = Error.Create("Fallo de stock.").WithReason("Sin unidades.");
var segundo = Error.Create("Fallo de pago.").WithReason("Tarjeta vencida.");
var combinado = ErrorComposer.Combine(primero, segundo);
var errores = combinado.ErrorsOfType<Error>(includeNonTerminal: true).ToArray();
Console.WriteLine(errores.Length); // 3: raíz agregada y dos errores.Para excluir la raíz agregada y conservar los errores con razones, usa combinado.ReasonsOfType<Error>(includeNonTerminal: true). El nombre «razones» expresa aquí su posición descendiente.