3

In my orchestration I have various steps that maps a flat file to 2 intermediate messages and eventually writes to SQL. First I made it without exception handling and it worked with a valid input file.

                msg0        msg1       msg2
┌──────┐  ┌─────┐  ┌───────┐  ┌───────┐  ┌─────┐
│ PIPE │-►│ RCV │-►│ MAP_1 │-►│ MAP_2 │-►│ SQL │
└──────┘  └─────┘  └───────┘  └───────┘  └─────┘

Now I'm trying to get the exceptions for every scope where I use a map. at the beginning of the orchestration, after the first Receive Shape, I put a Construct Message Shape that initializes all messages in the orchestration. I create the catch blocks (each with Construct shape for my fault_msg and its send shape), the FILE port, and build.

                             msg0          msg1          msg2
┌──────┐  ┌─────┐  ┌──────┬──┐  ┌───────┬──┐  ┌───────┬──┐  ┌─────┬──┐
│ PIPE │-►│ RCV │-►│ INIT │ex│-►│ MAP_1 │ex│-►│ MAP_2 │ex│-►│ SQL │ex│
└──────┘  └─────┘  └──────┴──┘  └───────┴──┘  └───────┴──┘  └─────┴──┘

VS KEEPS ASKING for msg initialization even in the map blocks for the messages that should enter ALREADY filled (or populated, or whatever the term is). Why is that?

EDIT: I figured out BT wants every msg initialized even when not used during exception handling. So I need to construct my custom fault message that will return the empty messages along with my custom fault message. In order to initialize them of course i need to declare at the beginning of the expression code this way:

    unusedMsg.Part = new System.Xml.XmlDocument();

Thing is now: the problem still comes out for the last mapping (sql):

           ┌──────────────────────┐
           │        scope         │
           │  ┌────────────────┐  │ 
┌──────┐   │  │      MAP       │  │    ┌────────┐
│ msg2 │ -►│  │ msg2  > sqlReq │  │ -► │ sqlReq │
└──────┘   │  └────────────────┘  │    └────────┘
           ├──────────────────────┤
           │         ex           │
           │  ┌────────────────┐  │
           │  │   construct    │  │    ┌────────┐
           │  │ msg2  > msgERR │  │ -► │ msgERR │
           │  └────────────────┘  │    └────────┘
           └──────────────────────┘

where it keeps asking this:

msg2.Part': message part has not been initialized in construct statement

and yet I know for sure that msg2 IS INITIALIZED because I had no exception producing it and I'm entering the new scope. How's that possible?

Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
strongmmc
  • 137
  • 12

1 Answers1

2

The error "message part has not been initialized in construct statement" occurs under the following circumstances in BizTalk

  1. Your construct shape is constructing the same message as one of the source messages. e.g in the following you need to remove msg2 from the messages constructed.

                  CORRECT                                  WRONG
           ┌──────────────────────┐               ┌──────────────────────┐
           │   CONSTRUCT MESSAGE  │               │   CONSTRUCT MESSAGE  │
           │ messages constructed │               │ messages constructed │
           │     sqlReq           │               │     sqlReq, msg2     │
           │  ┌────────────────┐  │               │  ┌────────────────┐  │
           │  │      MAP       │  │               │  │      MAP       │  │
           │  │ msg2  > sqlReq │  │               │  │ msg2  > sqlReq │  │
           │  └────────────────┘  │               │  └────────────────┘  │
           └──────────────────────┘               └──────────────────────┘
    
  2. You are constructing multiple messages in a construct shape, but a later message is dependent on you initialising another message earlier in the construct which is missing.

                  CORRECT                                  WRONG
           ┌──────────────────────┐               ┌──────────────────────┐
           │        Construct     │               │        Construct     │
           │ messages constructed │               │ messages constructed │
           │     sqlReq, sqlReq2  │               │     sqlReq, sqlReq2  │
           │  ┌────────────────┐  │               │                      │
           │  │      MAP       │  │               │                      │
           │  │ msg2  > sqlReq │  │               │                      │
           │  └────────────────┘  │               │                      │
           │  ┌────────────────┐  │               │  ┌────────────────┐  │
           │  │      MAP       │  │               │  │      MAP       │  │
           │  │sqlReq > sqlReq2│  │               │  │sqlReq > sqlReq2│  │
           │  └────────────────┘  │               │  └────────────────┘  │
           └──────────────────────┘               └──────────────────────┘
    

The error "use of unconstructed message" occurs with the following.

  1. You are trying to use a message as a source inside a scope that is neither initialized at the start of the scope nor prior to the construct shape inside the scope.

  2. You are trying to use a message in an exception block that was initialized inside the scope you are trying to catch an exception for.

  3. You are using a message after a scope that is only constructed in some of the scope areas. It needs to be constructed in all the scope areas.

Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
  • This confirmed that i wasn't wrong about the way i was handling my exception. for reasons related to VS property tab visibility, i didn't see that the construct shape was also specifying msg2 as one of the constructed msgs (maybe from a copy-paste). I'll keep this as a reference for future similar errors! thank you @Dijkgraaf – strongmmc Dec 07 '16 at 08:45
  • i modified accordingly... and it's still asking for this unused messages. Biztalk is testing my patience and my comprehension of the instrument dynamics as well. C# compiler never complains (warnings aside) for un-instanciated variables that are not used. They're named, and that's it... Why would a tool ask for instanciation of something that is not used during the process life cycle? – strongmmc Dec 07 '16 at 14:31
  • @strongmmc Looking at your question, after fixing the first error you would be hitting #3 for use of unconstructed message. You have to treat scopes the same way you do a try / catch block. Both your sqlReg & msgErr are created in only one part of the scope, so you cannot use either after the scope. I will try and add more details to my answer to highlight some patterns that you can use. P.S. Do you really only have a map in your scope? I would not usually try and catch an error from a single shape. – Dijkgraaf Dec 07 '16 at 19:07
  • Yes i separated one scope for map. I've been asked to produce a track message for every stage (this part is not included in the orch design above). Hence, the catch for each scope. I could have done it directly with a send port and some filters, and probably that's a mod i'm going to implement. – strongmmc Dec 08 '16 at 01:42
  • 1
    Here's another case that can cause this. I had an email, a multipart message type with two parts, a bodyPart and an attachmentPart. I copied a success email that had both, to an error email that only had bodyPart. The error email didn't need an attachment. Since I didn't set the attachmentPart, I got this error. Solution was to create a second multipart message type with only bodyPart in it. In summary, if you have a multi-part message, you need to set a value for each part. – NealWalters Feb 09 '21 at 16:40