error com error-handling

com - error handler vba



Implementación de ISupportErrorInfo: ¿qué significa? (1)

¿Qué significa la interfaz ISupportErrorInfo ? Estoy un poco perdido para entenderlo. Desde MSDN:

Esta interfaz asegura que la información de error pueda propagarse correctamente por la cadena de llamadas. Los objetos de automatización que utilizan las interfaces de manejo de errores deben implementar ISupportErrorInfo.

Este método indica si una interfaz es compatible con la interfaz IErrorInfo.

HRESULT InterfaceSupportsErrorInfo( REFIID riid );

¿Qué significa devolver S_OK en InterfaceSupportsErrorInfo ? ¿Deberías devolver S_OK para todas las interfaces? ¿Solo algunos?


Lo comprendo (basado en algunas páginas relacionadas de MSDN) es que al implementar ISupportErrorInfo , está indicando que una o más interfaces en su clase devuelven información de error llamando a SetErrorInfo , en lugar de simplemente devolver un error HRESULT .

Para ese fin, su implementación de ISuportErrorInfo::InterfaceSupportsErrorInfo debería devolver S_OK solo para aquellas interfaces en su clase que realmente usan SetErrorInfo para devolver información de error a la persona que llama, y solo a esas interfaces.

Por ejemplo, supongamos que tiene una clase que implementa una interfaz que escribió llamada IFoo que tiene un método DoSomething . Si alguien más crea una instancia de su clase y llama a IFoo::DoSomething , se supone que debe hacer lo siguiente si DoSomething devuelve un error HRESULT (parafraseando desde varias páginas de MSDN, pero comencé desde aquí: http://msdn.microsoft). com / en-us / library / ms221510.aspx ):

  • Llame a QueryInterface en el puntero IFoo para obtener la interfaz ISupportErrorInfo para el objeto que está implementando IFoo

  • Si el objeto llamado no implementa ISupportErrorInfo , la persona que llama tendrá que manejar el error en función del valor de HRESULT o pasarlo a la pila de llamadas.

  • Si el objeto llamado implementa ISupportErrorInfo , la persona que llama debería llamar a ISupportErrorInfo::InterfaceSupportsErrorInfo , pasando un REFIID para la interfaz que devolvió el error. En este caso, el método DoSomething de la interfaz IFoo devolvió un error, por lo que pasaría REFIID_IFoo (asumiendo que está definido) a InterfaceSupportsErrorInfo .

  • Si InterfaceSupportsErrorInfo devuelve S_OK , la persona que llama sabe en este punto que puede recuperar información más detallada sobre el error llamando a GetErrorInfo . Si InterfaceSupportsErrorInfo devuelve S_FALSE , la persona que llama puede suponer que la interfaz llamada no proporciona información detallada de error, y tendrá que confiar en HRESULT devuelto para descubrir qué sucedió.

El motivo de esta API de manejo de errores un tanto confusa / intrincada parece ser la flexibilidad (en lo que a mí respecta, de todos modos. Esto es COM después de todo;). Con este diseño, una clase puede admitir múltiples interfaces, pero no se requiere que todas las interfaces usen SetErrorInfo para devolver información de error de sus métodos. Puede tener ciertas interfaces seleccionadas en su clase que devuelven información de error detallada a través de SetErrorInfo , mientras que otras interfaces pueden seguir utilizando los HRESULT normales para indicar errores.

En resumen, la interfaz ISupportErrorInfo es una forma de informar al código de llamada que al menos una de las interfaces que implementa su clase puede devolver información detallada de error, y el método InterfaceSupportsErrorInfo le dice a la persona que llama si una interfaz determinada es una de esas interfaces. De ser así, la persona que llama puede recuperar la información detallada de error llamando a GetErrorInfo .