From: Don on 12 Jan 2007 14:18 When using Visual Basic .NET with a reference to Interop.Outlook, is there a way to get more detailed information about an error other than Exception.Message or Exception.ToString? For example, Outlook's MailItem.SaveAs method can return an error message of "The operation failed", but I have no idea what that means. As a test, I tried SaveAs using a filename that contained illegal characters and got the error message "Internal Application Error", which isn't helpful for explaining that particular error either. I suppose I could use a series of "Catch e As" derived Exception Types, but I'm not even sure what to include. Instead, can the "real" error simply be found in some property related to the base Exception Class object? Thanks!
From: Walter Wang [MSFT] on 14 Jan 2007 22:17 Hi Don, Managed and unmanaged code can work together to handle exceptions. If a method throws an exception in managed code, the common language runtime can pass an HRESULT to a COM object. If a method fails in unmanaged code by returning a failure HRESULT, the runtime throws an exception that can be caught by managed code. The runtime automatically maps the HRESULT from COM interop to more specific exceptions. For example, E_ACCESSDENIED becomes UnauthorizedAccessException, E_OUTOFMEMORY becomes OutOfMemoryException, and so on. If the HRESULT is a custom result or if it is unknown to the runtime, the runtime passes a generic COMException to the client. The ErrorCode property of the COMException contains the HRESULT value. In your specific case, the behavior is correct since the error returned from MailItem.SaveAs itself doesn't contain useful information. You can verify this by creating a simple macro in Outlook VBA and the error will be the same "The operation failed": Sub test() Dim f As Folder Set f = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox) Dim i As MailItem For Each i In f.Items i.SaveAs ("c:::1") Exit For Next End Sub Exception thrown from COM should be available in .NET through the IErrorInfo interface automatically. For example, if you create following COM component in VB6 which throws a exception: Public Sub Test() Err.Raise 12345, "Project1.Class1.Test()", "Custom exception from VB6" End Sub When you call it from VB.NET: Try Dim x As New Project1.Class1 x.Test() Catch e As Exception If TypeOf e Is System.Runtime.InteropServices.COMException Then Dim ce As System.Runtime.InteropServices.COMException = CType(e, System.Runtime.InteropServices.COMException) Stop End If End Try You will see: e.Message = "Custom exception from VB6" e.Source = "Project1.Class1.Test()" ce.ErrorCode = &H800A3039 The error code is composed of several parts, the last part is 12345 (&H3039): #Heath Stewart's Blog : Deciphering an HRESULT http://blogs.msdn.com/heaths/archive/2005/07/21/441391.aspx For more information why we need to check the exception type is a COMException or not: #Handling COM Interop Exceptions (.NET Framework Developer's Guide) http://msdn.microsoft.com/library/en-us/cpguide/html/cpconhandlingcominterop exceptions.asp?frame=true Hope this helps. Sincerely, Walter Wang (wawang(a)online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. If you are using Outlook Express, please make sure you clear the check box "Tools/Options/Read: Get 300 headers at a time" to see your reply promptly. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
From: Don on 16 Jan 2007 10:21 Hi Walter, Still having a problem... My test case calls MailItem.SaveAs using a filename having illegal characters. The error code returned in VB6 is x800300FC with a description of "Internal Application Error". I did find that passing that code to FormatMessage returns "The name %1 is not valid" which is much more useful (requires the use of the FORMAT_MESSAGE_IGNORE_INSERTS flag), so I'll do that in VB.NET. But the HRESULT returned in COMException.ErrorCode is different every time I run the application. I've gotten xA72300FC, xA0F300FC, xA30300FC, xA51300FC, etc. While the "300FC" portion of each HRESULT matches the "300FC" portion of the VB6 Error Code, the rest does not, so the lookup in FormatMessage fails. One solution apears to be to do a bit-wise AND of the HRESULT using x800FFFFF, which results in the proper code of x800300FC for each different HRESULT returned by the COMException. Is that a good solution, or is there another method that I should use to derive the proper Error Code for use with FormatMessage? Also, if using AND is correct, then is x800FFFFF okay, or to preserve both severity bits should it be xC00FFFFF? Thanks for your help, Don "Walter Wang [MSFT]" <wawang(a)online.microsoft.com> wrote... > > Exception thrown from COM should be available in .NET through the > IErrorInfo interface automatically. For example, if you create following > COM component in VB6 which throws a exception: > > Public Sub Test() > Err.Raise 12345, "Project1.Class1.Test()", "Custom exception from VB6" > End Sub > > When you call it from VB.NET: > > Try > Dim x As New Project1.Class1 > x.Test() > Catch e As Exception > If TypeOf e Is System.Runtime.InteropServices.COMException Then > Dim ce As System.Runtime.InteropServices.COMException = > CType(e, System.Runtime.InteropServices.COMException) > Stop > End If > End Try > > You will see: > > e.Message = "Custom exception from VB6" > e.Source = "Project1.Class1.Test()" > ce.ErrorCode = &H800A3039 > > The error code is composed of several parts, the last part is 12345 > (&H3039): > > Hope this helps. > > Sincerely, > Walter Wang (wawang(a)online.microsoft.com, remove 'online.') > Microsoft Online Community Support >
From: Walter Wang [MSFT] on 18 Jan 2007 04:43 Hi Don, A HRESULT is made up of following fields: * A 1-bit code indicating severity, where zero represents success and 1 represents failure. * A 4-bit reserved value. * An 11-bit code indicating responsibility for the error or warning, also known as a facility code. * A 16-bit code describing the error or warning. #HRESULT http://msdn2.microsoft.com/en-us/library/ms526450.aspx In case of COMException, you could use Marshal.GetExceptionForHR to convert the HRESULT to an exception again. It will return correct message for it: Imports Microsoft.Office.Interop.Outlook Imports System.Runtime.InteropServices Module Module1 Sub Main() Dim app As New Application() Dim inbox As MAPIFolder = app.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderInbox) For Each item As MailItem In inbox.Items Try item.SaveAs("?.msg") Catch e As System.Exception If TypeOf e Is COMException Then Dim ce As COMException = CType(e, COMException) Dim e2 As System.Exception = Marshal.GetExceptionForHR(ce.ErrorCode) Console.Write(e2.Message) Else Console.Write(e.Message) End If End Try Exit For Next End Sub End Module Hope this helps. Regards, Walter Wang (wawang(a)online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
From: Don on 18 Jan 2007 09:30 Hi Walter, I'm still having a problem getting the correct message. Using my MailItem.SaveAs test with illegal characters in the filename, Marshal.GetExceptionForHR(ce.ErrorCode) returned an Exception.Message as follows: "Exception from HRESULT: 0x8E6300FC" Ran the test again and got: "Exception from HRESULT: 0x928300FC" The HRESULT is different each time, and none of them appear to map to a description. Since the VB6 Error Code for this test is &H800300FC, don't I still need to convert ce.ErrorCode to a true COM Code when using GetExceptionForHR? For example, I tried Marshal.GetExceptionForHR(ce.ErrorCode And &H800FFFFF) instead, and the resulting Exception.Message was: "The name is not valid. (Exception from HRESULT: 0x800300FC (STG_E_INVALIDNAME))" which is basically what I'm looking for. So, is using "ce.ErrorCode And &H800FFFFF" the proper solution? And is &H800FFFFF the appropriate value for the filter? Thanks, Don "Walter Wang [MSFT]" <wawang(a)online.microsoft.com> wrote in message news:evemlUuOHHA.2304(a)TK2MSFTNGHUB02.phx.gbl... > In case of COMException, you could use Marshal.GetExceptionForHR to convert > the HRESULT to an exception again. It will return correct message for it: > > > Dim e2 As System.Exception = > Marshal.GetExceptionForHR(ce.ErrorCode) > Console.Write(e2.Message)
|
Next
|
Last
Pages: 1 2 3 Prev: MSSOAP errors Next: "object already exists" exception using RSACryptoServiceProvider |