I have a WCF service I use to submit bugs for my project. Snippet of the data class:
Private _exception As Exception
<DataMember()> _
Public Property Exception As Exception
Get
Return _exception
End Get
Set(ByVal value As Exception)
_exception = value
End Set
End Property
I have a Silverlight app that uses the WCF service to send any bugs home if and when they occur. This is the error I'm testing with:
Dim i As Integer = 5
i = i / 0
The problem is SL is banging on with this message:
System.ServiceModel.CommunicationException was unhandled by user code
Message=There was an error while trying to serialize parameter :bug. The InnerException message was 'Type 'System.OverflowException' with data contract name 'OverflowException:http://schemas.datacontract.org/2004/07/System' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
Is there some trick to get a generic .NET Exception (any InnerException) to serialize properly? I'm not doing anything funky with the exception - it's just a plain 'ol exception
Thanks for any help.
I doubt very much that you can serialize a .NET-specific type like an Exception. I recommend you create your own class to hold the parts of the exception you want serialized.
This may be a problem with implicitly casting the OverflowException into a System.Exception.
The data contract serializer is very specific. This can be good and bad.
I would try just throwing a new System.Exception to see if this works OK.
If this is the case, you may need to dumb down the exception, creating a new System.Exception with the original exception message in it.
Or, like John said, you might have a better go of it if you create a custom error class that holds the exception info.
Related
i'm studying kotlin.
I have a question about using exception.
which is better to use object exception or class exception in kotlin?
object CustomDuplicateId : RuntimeException("Invalid user with Id")
class CustomDuplicateId : RuntimeException("Invalid user with Id")
if im using this exception only one location, than stacktrace is always same.
so i think... it doesn't need to use class. is it right?
or is it bad to use singleton exception?
can anyone let me know what's better code to write exception?
There are multiple reasons why it's incorrect to use object.
the stacktrace is wrong in several ways:
It's created at instantiation time, so you'll see <clinit> as first line in the stacktrace because it's created when initializing the object's class for the first time
Even if you throw it from the same place, it won't necessarily be when called from the same caller, so the bottom (root) of the stacktrace will be incorrect if this exception is thrown multiple times across the life of your application
technically the exception class has mutable parts and it would be dangerous/incorrect to allow user code to tamper with this. A very concrete example of this is that user code could add suppressed exceptions to your exception instance (which would only be valid for one throw and yet persist in your object). This is technically a memory leak.
it's likely you would need different messages with more information about why it was thrown (in that case the duplicate ID is very much needed) - so you need different instances with different data anyway
you might throw it from different places in the future (even now in tests/mocks maybe?), and in that case the stacktrace would be even more wrong
independently of technicalities like the above, class vs object also sends a message to the reader that is a bit unclear - why an object here? This exception is not inherently unique. It just so happens that you throw it in one specific place right now and rely on the stacktrace being the same.
Here is an example for the major issue (#1):
object MyExceptionObject : RuntimeException("boom")
fun main() {
try {
caller1() // line 7
} catch (e: Exception) {
}
caller2() // line 10
}
fun caller1() = doStuff() // line 13
fun caller2() = doStuff() // line 14
fun doStuff() {
throw MyExceptionObject // line 17
}
The caller1() throws the exception but that one is caught. The caller2() throws the exception again and that one is not caught. The stacktrace we get for the uncaught exception incorrectly shows the caller 1 (with lines 7 and 13) but the correct one should be caller 2 (with lines 10 and 14):
Exception in thread "main" com.example.MyExceptionObject: boom
at com.example.MyExceptionObject.<clinit>(ExceptionObjectExample.kt)
at com.example.ExceptionObjectExampleKt.doStuff(ExceptionObjectExample.kt:17)
at com.example.ExceptionObjectExampleKt.caller1(ExceptionObjectExample.kt:13)
at com.example.ExceptionObjectExampleKt.main(ExceptionObjectExample.kt:7)
at com.example.ExceptionObjectExampleKt.main(ExceptionObjectExample.kt)
All in all, just use a class.
In SAP NetWeaver 7.52 I created an ABAP classed based exception that works fine while executing within a try catch clause in the report/program. But the custom message is not displayed in SAPGUI when the exception is not handled by a try catch clause.
What I'm looking for is that when no try catch is defined the exporting message used at the moment of the raise statements is shown in the "UNCAUGHT_EXCEPTION". I have tried redefining the get_text( ) and get_longtext( ) methods. But the ABAP Run time error does not give any useful information to the developer about the cause (which is stored in the "attr_message" attribute of the exception).
When using the "try catch" the message can be retrieved without problems, but the idea is that SAPGUI presents the developer the right message in the "ABAP Runtime Error" report.
zcx_adk_exception.abap
"! Base exception for all ABAP Development Kit (ADK) exceptions
class zcx_adk_exception definition public create public inheriting from cx_dynamic_check.
public section.
"! Initializes the exception message
"! #parameter message | Message related to the reason of the exception
methods constructor
importing value(message) type zadk_str optional.
"! Returns the message associated to the exception
methods get_message
returning value(result) type zadk_str.
methods if_message~get_text redefinition.
methods if_message~get_longtext redefinition.
private section.
data attr_message type zadk_str value ''.
endclass.
class zcx_adk_exception implementation.
method constructor ##ADT_SUPPRESS_GENERATION.
super->constructor( ).
if message is not initial.
me->attr_message = message.
endif.
endmethod.
method get_message.
result = me->attr_message.
endmethod.
method if_message~get_text.
result = me->get_message( ).
endmethod.
method if_message~get_longtext.
result = me->get_message( ).
endmethod.
endclass.
What works fine:
try.
raise exception type zcx_adk_exception exporting message = 'Base_Exception_Error'.
catch zcx_adk_exception into data(ex).
write: / 'Example 1:', ex->get_message( ).
write: / 'Example 2:', ex->get_text( ).
write: / 'Example 2:', ex->get_longtext( ).
endtry.
And the output is this:
What does not work:
" Not Catching the exception
raise exception type zcx_adk_exception exporting message = 'Base_Exception_Error'.
This results in the following message being displayed instead
Following the previously proposed idea of using a message I came up with the following code that allows the exception to be raised with a message. This allows the exception to show the right message when called within a "try catch" block and display a useful message in the "Error analysis" section of the dump generated by SAPGUI.
Solution:
"! Program to test functionalities and utilities
REPORT zsandbox_tests.
" Exception Class
CLASS lcl_exception DEFINITION INHERITING FROM cx_dynamic_check.
PUBLIC SECTION.
INTERFACES if_t100_dyn_msg.
METHODS if_message~get_text REDEFINITION.
METHODS constructor
IMPORTING VALUE(message) TYPE string.
PRIVATE SECTION.
DATA attr_message TYPE string VALUE ''.
ENDCLASS.
CLASS lcl_exception IMPLEMENTATION.
METHOD if_message~get_text.
result = attr_message.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
me->attr_message = message.
ENDMETHOD.
ENDCLASS.
" Class that raises the exception
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
CLASS-METHODS main RAISING lcl_exception.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA raise_message TYPE string VALUE 'Custom Message for the Exception'.
RAISE EXCEPTION TYPE lcl_exception
MESSAGE e000(lcl_exception) WITH raise_message '' '' '' " The if_t100_dyn_msg supports 4 attributes: V1, V2, V3 and V4 but I only use the first one
EXPORTING message = raise_message.
ENDMETHOD.
ENDCLASS.
" Call to Main Method
START-OF-SELECTION.
TRY.
lcl_main=>main( ).
CATCH lcl_exception INTO DATA(ex).
WRITE ex->get_text( ).
ENDTRY.
This generates the following output:
When no try catch is used:
" Call to Main Method
start-of-selection.
lcl_main=>main( ).
This is the output:
TL;DR : SAP did not plan to permit the customization of a short dump by the developer.
A "short dump" is a report which is generated by the ABAP kernel when an unexpected error occurs in an ABAP program, i.e. an error due to a bug in the program (usually an uncaught exception, or non-catchable errors) or to a system failure (input/output resources, memory resources, etc.)
It's intended to help the developer analyze the cause of the error and correct it.
It's not intended to be generated on purpose, except in a situation that the developer has made theoretically impossible, but actually happens, and which is thought to require many information to analyze if it happens, hence a short dump.
If it's really your intention to generate a short dump with a message, for some purpose, there are two ways:
MESSAGE 'message text' TYPE 'X'. (often used in standard SAP programs, especially in update function modules)
RAISE SHORTDUMP ... or ... THEN THROW SHORTDUMP ... in conditional expression. Both exist since ABAP 7.53. For instance RAISE SHORTDUMP TYPE zcx_adk_exception EXPORTING message = 'Base_Exception_Error'.
The short dump will contain the message text in the Analysis section.
I have converted a VB6 project to VB.NET using Visual Studio 2008. I have some code that throws an error for invalid cast type when for doa.Field to String Type.
Here is the code that I am working with:
If rstLogin.BOF = True And rstLogin.EOF = True Then
MsgBox("User name not found, please try again!", , "Login")
frmLogin.txtUserName.Focus()
System.Windows.Forms.SendKeys.Send("{Home}+{End}")
Else
If Trim(inPassword) = Clean(rstLogin.Fields.Item("PassWord")) Then
Call MoveUserRecord(rstLogin)
LogUserIn = True
Else
MsgBox("Invalid Password, please try again!", , "Login")
frmLogin.txtPassword.Focus()
System.Windows.Forms.SendKeys.Send("{Home}+{End}")
End If
End If
The error is:
Unable to cast COM object of type 'dao.FieldClass' to class type 'System.String'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
The error is thrown on the part of the code for the password.
If Trim(inPassword) = Clean(rstLogin.Fields.Item("PassWord")) Then
I have tried to add .ToString() to everything that I could add it to, and I still get the same error. Can someone please tell me what I am doing wrong, and how I can fix this?
Hans Passant was really close with is answer. In order for you to fix the error, and for your code to compile correctly. You will need to use:
rstLogin.Fields("PassWord").Value.ToString()
I have tested this, and I am sure that it will work.
I wrote a very simple code that reads and writes from a card. I got an error:
An unhandled exception of type
'System.Runtime.InteropServices.MarshalDirectiveException' occured in
ReadandWrite.exe
Additional information: PInvoke restriction: can not return variants.
Code Snippet:
Console.WriteLine("Address = 0x3c3, Value = 0x", MX4.r_1byte(963).ToString)
I am trying to understand the error and how to fix it.
Sounds like you're forgetting to declare an Interop Type for one or more of your Public methods/properties. See this MSDN thread.
I have methods which return interface and some methods which accepts interface as parameters. I am trying to use Net DataContractSerializer but I am getting following error...
The formatter threw an exception while
trying to deserialize the message:
There was an error while trying to
deserialize parameter
http://tempuri.org/:id. The
InnerException message was 'Error in
line 1 position 120. XML 'Element'
'http://tempuri.org/:id' does not
contain expected attribute
'http://schemas.microsoft.com/2003/10/Serialization/:Type'.
The deserializer has no knowledge of
which type to deserialize. Check that
the type being serialized has the same
contract as the type being
deserialized.'. Please see
InnerException for more details.
Please help me how to resolve this error....
If I use Netdatacontract attribute on Operation Contract, can i use DataContract and Datamember attribute on serializable class???
Thanks in advance...
Just guessing - the error seems to indicate the NetDataContractSerializer can't properly determine what type to deserialize your content into.
Could it be that you're not specifying the http://tempuri.org XML namespace to the deserializer??
Also, can you show the content of the InnerException, please?
Or second option: using the NetDataContractSerializer, you need to also share the data contracts between server and client, so that the client can deserialize to the exact same type as was defined on the server side. Are you missing this requirement, maybe??