Hi,
i’m new to entirex and this may seem a silly question, but here it goes.
using the .net wrapper i’m calling several natural programs on os390 and it works fine.
the question is, how do i provoque an error in my natural program so that the broker will throw an exception that i can catch in my .net client ?
something like in .net 'throw new ApplicationException(“this is a message that i want to pass from natural/os3900 to .net because of business constraints”); '
TIA
Luis Azedo
Hi Luis,
it depends on the type of error you want to test against. If you want to test the way your .NET program handles Broker exceptions, then it is quite easy. You could simply NOT register your RPC Server. When you issue a call to the non-registered service, you should receive the standard “00070007 - Service not registered” error message (this is the exception thrown by Broker).
If you would like to “throw” exceptions from you Natural program, based on business logic within your Natural application, then you might want to add an additional output field in your IDL file. You could name this field something like “App_Return_Code” or something like that and define it as a alpha field.
If you do throw and exception in your Natural program you can populate the proper message in this “App_Return_Code” field and based on the contents you can decided how to proceed.
I sometimes include an additional integer field as well, to make the error checking easier on the client side.
Here is an example of such an IDL file:
Library ‘AMS’ Is
Program ‘AMS001N’ Is
Define Data Parameter
1 order-id-nbr (n10) in out
1 order-type (a10) in out
1 rltd-order-id-nbr (n10) in out
1 order-rltd-type-cd (a5) in out
1 bsns-id-nbr-byr (n10) in out
1 order-sgnd-nm (a35) in out
1 cnctct-phone-nbr (a10) in out
1 user-id-ordr-vldtr (a8) in out
1 return-error (n4) out
1 return-messsage (a70) out
End-Define
Hope this helps. If not, let me know.
Regards
Theo
Hi Theo,
thanks for the answer and sorry for stating that i was looking for an easier to do this since that your solution is actualy what we’re using.
isn’t there a way to provoque some kind of error inside natural program that one could easily identify ? i’m new to all this but i see lots of docs about messages formats and codes, i was hoping that someone had some workaround.
btw, when i try to generate a function instead of a procedure i get an error on the c# template. my last parameter is called Result_Function and is A(8) Out only as the docs say us to do. any hint ?
as a suggestion i would put string parameters in ‘string’ instead of ‘StringBuilder’ (the wrapper could do the work for us ?)
Thanks
Luis Azedo
There really isn’t a direct way for a server program to get Broker to throw an error to the client. Where Broker is concerned, there are two possible scenarios:
1) server returns a response to the client
2) server fails to return a response to client
In scenario 1, there is no Broker error; it is then up to the server and client to have some other mechanism for communicating errors (e.g. response code in the broker buffer / IDL)
In scenario 2, your client will eventually get a timeout error from the Broker(error code 00740074).
regards,
- arp
Hi Luis,
If you actually want to do what you said in your first question: provoke a “Natural error”
you can just make a statement inside your Natural-code that moves an errornumber into the Natural system-variable *error-nr - like this:
MOVE 3148 TO *ERROR-NR
This will provoke the error-handling in Natural
- in this case database ot available.
Finn
Hi,
You could make a calculation on alphanumeric data in your Natural server program.
Thierry
Thierry Casier
Hi,
thank you, you saved my day. i’m going to pursue the first you sent.
is there a natural system-variable like *error-msg or *error-desc ? that would be an ideal solution because we’re dealing with a lot of programs and i believe we can’t get enough error numbers, we just neeed one that we’ll be able to tell what the error is in a short message.
Thanks Again
Luis Azedo
Allianz Portugal
- Doesn’t the standard error-handling of the RPC-server give you enough back to your RPC-client ?
Finn
Hi,
actually no, what we’re looking is how to provoque an error based on a business rule and catch the exception on the client side with the message from the business rule.
any thoughts ?
thanks
Hi Luis,
Finn is quite correct when he says that if you assign an error number to error-nr this error will be returned to your .NET client. Unfortunately you will only get the error number and no text. This might work for you, if not and you are interested in a more complete error message then I have the following suggestion.
You can assign user-defined error message using SYSERR. This way you can create new user-define messages, with unique error numbers and describe the error and associated behavior. What I propose is the following:
Do as Finn says, generate an error in your Natural program by assigning a user-defined error number to the error-nr variable. When you receive this error number within your .NET program call a special RPC Service, with the error number, which in turn will read the user-defined error number and return the proper text to your .NET program.
This solution would have several advantages (and one disadvantage). The advantages include:
- User defined message are managed in a central location and you don’t have to hardcode all the messages description within your programs.
- You can extend these user-define error messages easily.
- You can support various languages (if this is of any concern).
- You can support different applications in exactly the same way and provide errors with the same error numbers, but which would be unique within the context of the Natural Library.
The disadvantage of this approach is that you will have to do an additional RPC call to get all the relevant user-defined error information.
Here is an example of what the IDL file would look like and the corresponding Natural program:
IDL File
library ‘THEOL’ is
program ‘RPCERROR’ is
define data parameter
1 application (a8)
1 error-number (n4)
1 language (i1)
1 response (n4)
1 short-text (a65)
end-define
Subprogram - RPCERROR
define data parameter
1 #parameters
2 #application (a8)
2 #error-number (n4)
2 #language (i1)
2 #response (n4)
2 #short-text (a65)
END-DEFINE
callnat ‘USR0320N’ #parameters
end
For testing purposes I went into SYSERR and added an error message with error number 0999 and description Special Exception Thrown by Natural Program.
When calling the RPCERROR program I would pass the following parameters:
application = THEOL
error-number = 999
language = 1
This would return the proper message description. In your case the language would most probably be set to “B” - Portuguese.
Obviously the application will correspond to your Natural library.
Also note that USR0320N is a user exit that can be found in the SYSEXT library. This program only returns the short error message. If you would like to return the long error message then I suggest you look at USR0420N. Also USR0020N can be used to read both user-defined as well as Natural error messages.
I hope you find this helpful.
Regards
Theo
Hi All,
thank you verymuch for your replies.
taking the secong aproach ( 2 calls when theres an error ) seems to be answer we were waiting ,we tried, and it works for static messages.
the problem is that business tend to be dynamic (based on table values and other processors) so the messages always have a variable part like ‘Can only accept {0} for this policy’ so we tried working with variables on messages but it seems that we can’t assign the values (on a screen map it works with reinput i presume)
, also when the second call is made we already lost the values for these variables.
we took a look deeper in sysrpc and there is subprogram called ‘NATRPC01’ that seems to do some sort of tracing stating in the notes that it is called just before the answer is sent back to the client, sending up to 6 lines of trace messages. unfortunally we couldn’t pursue this option deeper (tight schedule), and i was wondering if anyone as ever tried this and how do we put our own text in this trace space passing it to the client and reading it on the client, i’m confused about the sequence.
TIA
Luis Azedo
Hi Luis,
there might be a ?simple? solution to your problem; you could User Exit (USR0421N) to update the short error message description, as it is stored in FUSER.
When you want to “throw” the exception in your program you can read the error message (using USRN0320N) and update the description (using USRN0421N). I have not evaluated the advantages and disadvantages of doing so, but I’m sure you will. Some of the things to think about are:
1) What happens if more than one program wants to throw the same error? If several programs try to throw the same error (or actually do) then they might overwrite each other?s messages.
2) The solution to this would be for you to ensure that each error number is unique (and maybe tied to the program that is throwing the error), this will ensure that the program will be able to update the error message without problems . . . unless there is more than one instance of the same program running, which could mean that the various instances could potentially overwrite each other?s messages.
3) This leads me to think that you should try to devise a scheme by which the error number would be unique for each error instance being thrown. But again I can come up with several scenarios where you will run into limitations and possible conflicts.
4) Having stated the above, it appears that the solution is not nearly as simple or elegant as I initially would have liked.
I will give it some more thought and maybe you can too. Hopefully you will be able to come up with a scheme that works for you. When you first raised the question I also initially considered using NATRPC01, but it appears that the error message generated is written to the RPC trace. I could be mistaken and maybe someone who has more insight into NATRPC01 can shed some light on it.
Lastly, the more I think about it the more it makes sense to keep things simple. A simple and easy solution might be the best approach; the initial method of providing the exception message directly within a field as the end of the RPC call structure might be your best bet. Do you have specific objections to this method?
Regards
Theo
Hi,
thanks for the reply.
actually i was hoping that EntireX Communicator had support for runtime type error in a easier way.
my latest solution is as follows, please advice me if think thats the wrong way.
1) every sub-program has 3 extra parameters
a) Error-Code
b) Message-Number (for long messages, helps, etc )
c) Description
2) customize the template for c# in a way that you expose the methods without these extra parameters, creating a proxy and expose this instead of the rpc object.
3) the proxy object should take care of calling the realproxy.
4) catch any entirex exceptions in this object and try to obtain the message (short text), throw this exception with the short-text if available, if not throw the original.
5) check the return code from the business object. if != 0 throw an exception with the description and a link to obtain the long text
i think this is it. the hard work will be customizing the template.
what do you think ?
maybe SoftwareAG will include this kind of functionality in a future version.
TIA
Luis Azedo
Allianz Portugal
Hi Luis,
an alternative option to modifying the template could be a class that inherits from the .NET Wrapper generated wrapper class, overrides those methods that require exception handling and handles the error parameter(s). (Wouldn’t one error string parameter be sufficient?)
The solution would then briefly be as follows:
- add one (or more) extra error parameter(s) to the
programs exposed via RPC
- generate a .NET wrapper class
- write a custom class that inherits from the wrapper class,
overrides the methods with the error parameter(s), and throws
an exception in case of an error
Modifying the template bares the risc, that you run out of sync with updated templates shipped with future versions and updates of EntireX Communicator.
Regards, Dietmar.
Hi Luis,
Dietmar made a good suggestion and I agree that his idea is the safer approach. Modifying the template files could create additional maintenance and also upgrade problems, when new releases of EntireX come out or when R&D modifies the template files.
I think Dietmar?s approach is a much safer option.
Theo