Error handling in simulatenous loops
I am trying to design a good error handling system for a project I am working on, but I have run into a "design" problem. I thought it would be good to ask for some guidance here before I sit down and start create the error handling system.
I have more than one subVI started from one mainVI, each subVI with an individual while loop running (they all stop when I press the same stop button from the mainVI). Each while loop continously retrievews information from various serial devices. Each VISA call etc. can thus of course generate errors. I only want one error dialog box in my mainVI front panel displaying any error that happens.
How would I design this in a good way? As I see it, I would have to use the error dialog box in the mainVI as a global/functional global. Each subVI would then write to this global error dialog box. This could however cause race conditions where only the latest error gets displayed even if earlier errors happened. Appreciate some good advice here.
Solved!
Go to Solution.
First and foremost I would avoid using the sequence structure. LabVIEW is a data flow language and you should take advantage of that rather than forcing it to be a sequenctial language. Take a look various examples that ship with LabVIEW. You will want to definitely check out the examples for state machines and the producer consumer architectures. Your current code will not meet your needs of continually monitoring for errors since your "Error" queue is not in a parallel loop task.
I have attached a very quik example of a producer consumer architecture with an error processing loop. There are no real code details but this is a simple example of an approach to take for an application. This along with the above examples should give you a decent starting point.
Message Edited by Mark Yedinak on 10-05-2009 04:05 PM
Mark Yedinak
"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Attachments:
Simple Application Architecture (8-6).vi 13 KB
Similar Messages
-
How to perform Error Handling in this Bdc Code
Hi,
I had created this BDC for the tcode MB1B and i want to know how to perform the ERROR HANDLING in it ..
Plzz provide me guidelines for doing it . here's d code:-
report ZBDC_MB1B
no standard page heading line-size 255.
include bdcrecx1.
data: begin of record OCCURS 0,
WERKS_001(004), "Plant
MATNR_002(018), "ItemId
ERFMG_003(013), "Quantity in Unit of Entry
ERFME_004(003), "Unit of Entry
LGORT_005(004), "Storage Location
CHARG_006(010), "BatchId
KDAUF_007(010), "Sales Order Number
KDPOS_008(006), "Item Number in Sales Order
end of record.
PARAMETERS : P_FILNAM LIKE RLGRAP-FILENAME.
initialization.
CTUMODE = 'A'.
CUPDATE = 'A'.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILNAM.
CALL FUNCTION 'WS_FILENAME_GET'
EXPORTING
MASK = ',. '
MODE = 'O'
IMPORTING
FILENAME = P_FILNAM
EXCEPTIONS
INV_WINSYS = 1
NO_BATCH = 2
SELECTION_CANCEL = 3
SELECTION_ERROR = 4
OTHERS = 5
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
start-of-selection.
CALL FUNCTION 'WS_UPLOAD'
EXPORTING
FILENAME = P_FILNAM
FILETYPE = 'DAT'
TABLES
DATA_TAB = RECORD
EXCEPTIONS
CONVERSION_ERROR = 1
FILE_OPEN_ERROR = 2
FILE_READ_ERROR = 3
INVALID_TYPE = 4
NO_BATCH = 5
UNKNOWN_ERROR = 6
INVALID_TABLE_WIDTH = 7
GUI_REFUSE_FILETRANSFER = 8
CUSTOMER_ERROR = 9
NO_AUTHORITY = 10
OTHERS = 11
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
LOOP AT RECORD.
BEGIN OF SCREEN 1
perform bdc_dynpro using 'SAPMM07M' '0400'.
perform bdc_field using 'BDC_CURSOR'
'RM07M-SOBKZ'.
perform bdc_field using 'BDC_OKCODE'
'/00'.
*perform bdc_field using 'MKPF-BLDAT'
'22.12.2008'.
*perform bdc_field using 'MKPF-BUDAT'
'22.12.2008'.
perform bdc_field using 'RM07M-BWARTWA'
'411'.
perform bdc_field using 'RM07M-SOBKZ'
'E'.
perform bdc_field using 'RM07M-WERKS'
RECORD-WERKS_001. "Plant
perform bdc_field using 'XFULL'
'X'.
perform bdc_field using 'RM07M-WVERS2'
'X'.
BEGIN OF SCREEN 2
perform bdc_dynpro using 'SAPMM07M' '0421'.
perform bdc_field using 'BDC_CURSOR'
'MSEG-CHARG(01)'.
perform bdc_field using 'BDC_OKCODE'
'/00'.
perform bdc_field using 'MSEG-MATNR(01)'
RECORD-MATNR_002. "ITEMID
perform bdc_field using 'MSEG-ERFMG(01)'
RECORD-ERFMG_003. "QTY.
perform bdc_field using 'MSEG-ERFME(01)'
RECORD-ERFME_004. "UOM
perform bdc_field using 'MSEG-LGORT(01)'
RECORD-LGORT_005. "ST.LOC
perform bdc_field using 'MSEG-CHARG(01)'
RECORD-CHARG_006. "BATCHID
perform bdc_field using 'MSEGK-MAT_KDAUF'
RECORD-KDAUF_007. "S.O.
perform bdc_field using 'MSEGK-MAT_KDPOS'
RECORD-KDPOS_008. "S.O.LINE ITEM
perform bdc_field using 'DKACB-FMORE'
'X'.
BEGIN OF SCREEN 3
perform bdc_dynpro using 'SAPLKACB' '0002'.
perform bdc_field using 'BDC_OKCODE'
'=ENTE'.
perform bdc_field using 'DKACB-FMORE'
'X'.
perform bdc_dynpro using 'SAPLKACB' '0002'.
perform bdc_field using 'BDC_OKCODE'
'=ENTE'.
perform bdc_dynpro using 'SAPMM07M' '0421'.
perform bdc_field using 'BDC_CURSOR'
'MSEG-ERFMG(01)'.
perform bdc_field using 'BDC_OKCODE'
'=BU'.
perform bdc_field using 'DKACB-FMORE'
'X'.
BEGIN OF SCREEN 4
perform bdc_dynpro using 'SAPLKACB' '0002'.
perform bdc_field using 'BDC_OKCODE'
'=ENTE'.
perform bdc_transaction using 'MB1B'.
ENDLOOP.hi,
check this code in bold letters.
INCLUDE BDCRECX1.
TABLES : MARC.
TYPES : BEGIN OF TY_UPLOAD,
MATNR TYPE MARA-MATNR,
WERKS TYPE MARC-WERKS,
STEUC TYPE MARC-STEUC,
END OF TY_UPLOAD.
TYPES : BEGIN OF TY_MARC,
MATNR TYPE MARA-MATNR,
WERKS TYPE MARC-WERKS,
END OF TY_MARC.
TYPES : BEGIN OF TY_MTART,
MATNR TYPE MARA-MATNR,
MTART TYPE MARA-MTART,
END OF TY_MTART.
DATA : T_MARC TYPE STANDARD TABLE OF TY_MARC,
: T_UPLOAD TYPE STANDARD TABLE OF TY_UPLOAD,
: T_BASIC TYPE STANDARD TABLE OF TY_UPLOAD,
: T_SALES TYPE STANDARD TABLE OF TY_UPLOAD,
: T_ERROR TYPE STANDARD TABLE OF TY_UPLOAD.
DATA : IT_BDCDATA LIKE BDCDATA OCCURS 0 WITH HEADER LINE,
IT_BDCDATA_VIEW LIKE BDCDATA OCCURS 0 WITH HEADER LINE,
IT_DATA(3200) OCCURS 0 WITH HEADER LINE,
IT_FIELD(3200) OCCURS 0 WITH HEADER LINE,
IT_BDCMSG TYPE BDCMSGCOLL OCCURS 0 WITH HEADER LINE.
DATA GI_MSG LIKE BDCMSGCOLL OCCURS 0 WITH HEADER LINE.
DATA : CHAR1(500),
CHAR2(500),
CHAR3 TYPE STRING,
V_SELECTION TYPE STRING. " For View Selection
DATA : W_MARC TYPE TY_MARC,
WA_UPLOAD TYPE TY_UPLOAD,
WA_BASIC TYPE TY_UPLOAD,
WA_SALES TYPE TY_UPLOAD,
WA_ERROR TYPE TY_UPLOAD,
WA_MTART TYPE TY_MTART.
DATA : VAR TYPE N,
VAR1 TYPE STRING.
SELECTION-SCREEN : BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-001. "SELECTION SCREEN
PARAMETERS: P_FNAM LIKE RLGRAP-FILENAME.
PARAMETERS: P_BAS LIKE RLGRAP-FILENAME.
PARAMETERS: P_SAL LIKE RLGRAP-FILENAME.
PARAMETERS: P_ERR LIKE RLGRAP-FILENAME.
SELECTION-SCREEN : END OF BLOCK B1.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FNAM.
PERFORM SEARCH USING P_FNAM.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_BAS.
PERFORM SEARCH USING P_BAS.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_SAL.
PERFORM SEARCH USING P_SAL.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_ERR.
PERFORM SEARCH USING P_ERR.
*& Form SEARCH
text
-->PFNAME text
FORM SEARCH USING PFNAME.
CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
EXPORTING
STATIC = 'X'
CHANGING
FILE_NAME = PFNAME.
ENDFORM. "SEARCH
START-OF-SELECTION.
PERFORM UPLOAD_PROCESS USING P_FNAM.
PERFORM OPEN_GROUP.
PERFORM PROCESS.
PERFORM CLOSE_GROUP.
IF NOT T_BASIC[] IS INITIAL.
PERFORM DOWNLOAD TABLES T_BASIC[] USING P_BAS .
ENDIF.
IF NOT T_SALES[] IS INITIAL.
PERFORM DOWNLOAD TABLES T_SALES[] USING P_SAL .
ENDIF.
IF NOT T_ERROR[] IS INITIAL.
PERFORM DOWNLOAD TABLES T_ERROR[] USING P_ERR.
ENDIF.
*& Form PROCESS
text
FORM PROCESS.
LOOP AT T_UPLOAD INTO WA_UPLOAD.
PERFORM CONV_ROUTINE USING WA_UPLOAD-MATNR
CHANGING WA_UPLOAD-MATNR.
SELECT COUNT(*) FROM MARA WHERE MATNR = WA_UPLOAD-MATNR.
IF SY-SUBRC NE 0.
MOVE-CORRESPONDING WA_UPLOAD TO WA_BASIC.
APPEND WA_BASIC TO T_BASIC.
CLEAR WA_BASIC.
CONTINUE.
ENDIF.
SELECT COUNT(*) FROM MARC WHERE MATNR = WA_UPLOAD-MATNR
AND WERKS = WA_UPLOAD-WERKS
AND PSTAT LIKE '%V%'.
IF SY-SUBRC NE 0.
MOVE-CORRESPONDING WA_UPLOAD TO WA_SALES.
APPEND WA_SALES TO T_SALES.
CLEAR WA_SALES.
CONTINUE.
ENDIF.
CLEAR : WA_MTART.
SELECT SINGLE MATNR MTART FROM MARA INTO WA_MTART WHERE MATNR = WA_UPLOAD-MATNR.
PERFORM BDC_DYNPRO USING 'SAPLMGMM' '0060'.
PERFORM BDC_FIELD USING 'BDC_CURSOR'
'RMMG1-MATNR'.
PERFORM BDC_FIELD USING 'BDC_OKCODE'
'=AUSW'.
PERFORM BDC_FIELD USING 'RMMG1-MATNR'
WA_UPLOAD-MATNR.
CALL FUNCTION 'MATERIAL_BTCI_SELECTION_NEW' " Function module
EXPORTING
MATERIAL = WA_UPLOAD-MATNR " Material number
MATERIALART = WA_MTART-MTART " Material Type
SELECTION = 'V' "
TCODE = 'MM02' " Tcode where view's are called.
TABLES
BTCI_D0070 = IT_BDCDATA_VIEW
EXCEPTIONS
MATERIAL_NOT_FOUND = 1
MATERIAL_NUMBER_MISSING = 2
MATERIAL_TYPE_MISSING = 3
MATERIAL_TYPE_NOT_FOUND = 4
NO_ACTIVE_DYNPRO_SELECTED = 5
NO_AUTHORITY = 6
OTHERS = 7.
READ TABLE IT_BDCDATA_VIEW WITH KEY FVAL = 'X'.
IF SY-SUBRC = 0.
V_SELECTION = IT_BDCDATA_VIEW-FNAM.
ELSE.
CONTINUE.
ENDIF.
VAR = IT_BDCDATA_VIEW-FNAM+17(2).
VAR = VAR + 3.
CONCATENATE 'MSICHTAUSW-KZSEL(' '0' VAR ')' INTO VAR1.
PERFORM BDC_DYNPRO USING 'SAPLMGMM' '0070'.
PERFORM BDC_FIELD USING 'BDC_CURSOR'
'MSICHTAUSW-DYTXT(06)'.
PERFORM BDC_FIELD USING 'BDC_OKCODE'
'=ENTR'.
PERFORM BDC_FIELD USING VAR1
'X'.
CLEAR VAR.
CLEAR VAR1.
PERFORM BDC_FIELD USING 'MSICHTAUSW-KZSEL(06)'
'X'.
PERFORM BDC_DYNPRO USING 'SAPLMGMM' '0080'.
PERFORM BDC_FIELD USING 'BDC_CURSOR'
'RMMG1-VKORG'.
PERFORM BDC_FIELD USING 'BDC_OKCODE'
'=ENTR'.
PERFORM BDC_FIELD USING 'RMMG1-WERKS'
WA_UPLOAD-WERKS.
PERFORM BDC_DYNPRO USING 'SAPLMGMM' '4004'.
PERFORM BDC_FIELD USING 'BDC_OKCODE'
'=BU'.
PERFORM BDC_FIELD USING 'MAKT-MAKTX'
'MTI_ESE_HALB_01'.
PERFORM BDC_FIELD USING 'MARC-STEUC'
WA_UPLOAD-STEUC.
PERFORM BDC_FIELD USING 'BDC_CURSOR'
'MARC-HERKR'.
PERFORM BDC_FIELD USING 'MARC-HERKL'
'IN'.
PERFORM BDC_FIELD USING 'MARC-HERKR'
'MAH'.
PERFORM BDC_TRANSACTION USING 'MM02'.
move the error record into seperate internal table nad down load it ****
IF MESSTAB-MSGTYP = 'E'.
MOVE-CORRESPONDING WA_UPLOAD TO WA_ERROR.
APPEND WA_ERROR TO T_ERROR.
CLEAR WA_ERROR.
ENDIF.
ENDLOOP.
ENDFORM. "PROCESS
*& Form UPLOAD_PROCESS
text
-->PFNAME text
FORM UPLOAD_PROCESS USING PFNAME.
DATA : PFNAME1 TYPE STRING.
PFNAME1 = PFNAME.
CALL FUNCTION 'GUI_UPLOAD'
EXPORTING
FILENAME = PFNAME1
FILETYPE = 'ASC'
HAS_FIELD_SEPARATOR = 'X'
TABLES
DATA_TAB = T_UPLOAD[].
IF SY-SUBRC <> 0.
ENDIF.
ENDFORM. "UPLOAD_PROCESS
*& Form CONV_ROUTINE
text
-->P_INPUT text
-->P_OUTPUT text
FORM CONV_ROUTINE USING P_INPUT
CHANGING P_OUTPUT.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
INPUT = P_INPUT
IMPORTING
OUTPUT = P_OUTPUT.
ENDFORM. "CONV_ROUTINE
*& Form DOWNLOAD
text
-->GI_FINAL text
-->PFNAME text
FORM DOWNLOAD TABLES
GI_FINAL
USING PFNAME .
DATA : FNAME TYPE STRING.
FNAME = PFNAME.
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
FILENAME = FNAME
FILETYPE = 'DAT'
WRITE_FIELD_SEPARATOR = 'x'
HEADER = '00'
IMPORTING
FILELENGTH =
TABLES
DATA_TAB = GI_FINAL[]
FIELDNAMES = GI_FIELDNAMES[]
IF SY-SUBRC = 0.
MESSAGE 'FILE DOWNLOADED SUCCESSFULLY' TYPE 'I'.
ENDIF.
ENDFORM. " DOWNLOAD
Regards
Siva Prasad -
Error-handling in PKGBUILDs is far from perfect
Hi, PKGBUILDs should die on failure, rather than just continue regardless of errors. Here's a little rant:
Why is it acceptable for ./configure to fail? Or make install to fail? Or the installation of just about any file? They could fail for lots of reasons, such as expecting a non-existent directory to exist, just being badly-written, or disk corruption, or running out of disk space. I see this lack of error-handling both in official packages and in the AUR.
Failing on an error is a fundamental part of programming, and BASH makes a mockery of it. And then Linux developers seem to get brainwashed by BASH into believing that mixing important and non-important errors together, then just ignoring all the errors, is an acceptable programming practice. It's not - it's a comedy of errors (excuse the pun).
SourceMage handles this problem by having one huge command constructed with && at the end of each line, so at least will fail on error.
Gentoo is using its custom die command more often these days (|| die), but my proposal is in limbo, presumably because "SpanKY" overrules every other dev (little bit of Gentoo politics there ).
The current practice of make || return 1 is correct, but || return 1 should be used far more often - example (notice the looped use of install, and the annoyance of having to check $? after the loop). "More often" includes make install even if it's on the final line, both for consistency, and so it is not forgotten to be added when further lines are added to the end (e.g. to install the license/documentation files).
I'll place this on flyspray after a bit of feedback.
Edit: I'll distro-hop instead.
Last edited by brebs (2008-04-21 13:55:33)I'm as guilty as anyone in this. However, I always use it on the initial "configure" and "make install" lines where there is a lot of output. I tend to miss it when installing individual files at the end (e.g. Licences, icons...) because I can see if they failed from the output.
-
'Structured' error handling and reentrancy
The parentheses in the subject are due to the fact that I'm not using the Structured Error Handler reference library, but have rolled my own to do something similar but in the manner I want it to. I don't actually use the SEH (haven't even got it installed at the moment on this PC) so am not sure exactly how it works under the hood.
I have a reasonably large application with a number of distinct parallel modules (GUI, state module, communication, motion control). The final parallel module is an error handling module. This consists of two queues - one for incoming errors, and one for outgoing actions. Errors are dequeued and their codes checked for their category (critical, warning, ignore or unclassified, for instance) and the appropriate category is returned to a local error handler via the action queue. When an error is passed to a local error handler VI, it enqueues the error to the main handler and waits for a response to that particular error.
This all works nicely, in much the same way the SEH would do. However, with either the SEH or my local error handler method, I find myself wondering how often to place these down and the consequences of doing so. If they're non-reentrant, I imagine I may end up with lots of parallel processes sitting patiently to access the VI as it's blocked by another, causing jitter. If I go pre-allocated clone, I could potentially have many many callers using this function, which strikes me as a bit of a waste of resources. My gut feel is to go with shared-allocation clones, as the vast majority of the time it'll be no error passed through an empty case, and not to place them in absolutely every subVI - just perhaps after a state executes in the state handler, in all the parallel loops of the submodules etc.
Just wondering what anyone else does with their error handling solution, and whether my thoughts make sense.
CLDHaving chatted to my friendly neighbourhood Spiderman Architect, he suggested I should probably just stop being a wimp and just use pre-allocated clones to avoid the jitter and to stop worrying about the resource hit, as you suggest
I'll use the same code on both PC host and RT host, hence the jitter concerns on the RT.
Thanks for the thoughts!
CLD -
Error handling in bdc Fb01along with erros in Idoc.
Hi,
Can any one send me the sample code for the error handling in bdc Fb01along with erros in Idoc. Actually, mail should be sent
Thanks
Avi.Hi,
This may help you.
<b>FORM send_mail USING receiver.
CLEAR: w_lines,tbl_packing_list,tbl_object_header,
tbl_contents_txt, tbl_receivers.
REFRESH:tbl_packing_list, tbl_object_header,
tbl_contents_txt,tbl_receivers.
SORT tbl_err.
DELETE ADJACENT DUPLICATES FROM tbl_err COMPARING ALL FIELDS.
IF NOT tbl_err[] IS INITIAL.
Preparing the email.
PERFORM prepare_email.
ELSE.
If sy-subrc NE 0.
MOVE sy-subrc TO w_code.
ENDIF.
EXIT.
ENDIF.
Get the content of header e-mail document data
PERFORM document_data.
Get details of the error file attached (like type of file and format)
PERFORM packing_list.
Get receiver mail id's
tbl_receivers-receiver = receiver.
tbl_receivers-rec_type = 'C'.
tbl_receivers-express = c_flag.
tbl_receivers-sap_body = c_flag.
APPEND tbl_receivers.
Call FM to send E-mails to receivers
CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
EXPORTING
document_data = st_document_data
put_in_outbox = 'X'
TABLES
packing_list = tbl_packing_list
object_header = tbl_object_header
contents_txt = tbl_contents_txt
receivers = tbl_receivers[]
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
ENDFORM. " send_mail
*& Form prepare_email
text
--> p1 text
<-- p2 text
FORM prepare_email.
E-Mail body content
IF NOT w_lifnr IS INITIAL.
CONCATENATE text-015 w_docnum text-016
INTO tbl_contents_txt-line
SEPARATED BY space.
ENDIF.
APPEND tbl_contents_txt.
CLEAR tbl_contents_txt.
E-mail error file attachment header
CONCATENATE text-063 text-064
text-065 text-066 c_comma
INTO tbl_contents_txt-line
SEPARATED BY c_comma.
APPEND tbl_contents_txt.
CLEAR tbl_contents_txt.
E-mail error file attachment content
LOOP AT tbl_err.
CONCATENATE w_docnum tbl_err-v_segnum
tbl_err-msg tbl_err-type
INTO tbl_contents_txt-line
SEPARATED BY c_comma.
CONCATENATE c_linefeed tbl_contents_txt-line c_comma
INTO tbl_contents_txt-line.
APPEND tbl_contents_txt.
CLEAR tbl_contents_txt.
ENDLOOP.
ENDFORM. " prepare_email
*& Form document_data
text
--> p1 text
<-- p2 text
FORM document_data.
CLEAR w_line.
IF NOT w_lifnr IS INITIAL.
CONCATENATE text-075 text-027 sy-datum sy-uzeit INTO w_line
SEPARATED BY c_uscore.
ENDIF.
st_document_data-obj_name = w_line.
st_document_data-obj_descr = w_line.
st_document_data-priority = 1.
st_document_data-obj_prio = 1.
ENDFORM. " document_data
*& Form packing_list
text
--> p1 text
<-- p2 text
FORM packing_list.
CLEAR w_lines.
DESCRIBE TABLE tbl_err LINES w_lines.
READ TABLE tbl_contents_txt INDEX w_lines.
tbl_packing_list-head_start = 1.
tbl_packing_list-head_num = 1.
tbl_packing_list-body_start = 1.
tbl_packing_list-body_num = 1.
tbl_packing_list-doc_type = 'RAW'.
APPEND tbl_packing_list.
tbl_packing_list-head_start = 1.
tbl_packing_list-head_num = 0.
tbl_packing_list-body_start = 2.
tbl_packing_list-body_num = w_lines + 1.
tbl_packing_list-doc_type = 'CSV'.
tbl_packing_list-obj_descr = 'Error_Attachment'(060).
IF NOT w_lifnr IS INITIAL.
tbl_packing_list-obj_name = 'Idoc Number is'(072).
ENDIF.
tbl_packing_list-doc_size = 255 * ( w_lines + 1 ).
APPEND tbl_packing_list.
ENDFORM. " packing_list
</b>
Thanks
Manju. -
Error handling in the InDesign SDK
I've almost reached the first milestone on my InDesign project and before I move on I decided to do a code review. One thing that caught my attention are the InDesign smart pointers and how they are used in the SDK samples and some of the open source stuff.
For example, here is some code from AppearancePlaceBehaviourUI.cpp in function GetCursor().
InterfacePtr<IHierarchy> sourceItem(const_cast<AppearancePlaceBehaviorUI*>(this), UseDefaultIID());
InterfacePtr<IHierarchy> parentItem(sourceItem->QueryParent());
InterfacePtr<IPlaceBehavior> parentBehavior(parentItem, UseDefaultIID());
if (parentBehavior == nil)
InterfacePtr<IHierarchy> sourceContent(sourceItem->GetChildCount() ? sourceItem->QueryChild(0) : nil);
if (sourceContent)
InterfacePtr<IPlaceBehaviorUI> sourceBehaviorUI(sourceContent, UseDefaultIID());
cursor = sourceBehaviorUI->GetCursor(globalLocation, modifiers);
Although the code works under normal circumstances, it strikes me as unsafe code.
sourceItem->QueryParent() is called without first checking that sourceItem is not a NULL pointer.
Functions of the sourceItem object are used again (GetChildCount() and QueryChild()).
The pointer sourceContent is checked before passing it to the constructor of sourceContent.
Function GetCursor() is called without checking if sourceBehaviourUI is not NULL.
For code tidiness pointers should really be tested against nil (i.e. if (ptrSomeObject != nil))
It strikes me as being inconsistent and easy to break - unless that is some of these interfaces are guaranteed to return pointers, in which case is there documentation to state as much? What would happen in the case of an exception such as bad_alloc - are they guaranteed not to throw?
I know that in some places (but not all), the samples use an "exception-style" approach of placing code blocks within a "do while(kFalse)" statement. They check for a NULL pointer and if they find one, break out of the "loop". This approach avoids deep nesting code.
It would be great if Adobe gave a statement stating what their code base will do and won't do (i.e. exception safety). A few definative error handling examples for developers wouldn't go amiss either.Hi Dirk,
Agreed - I also would like to see more real world source code that explains concepts. It would be good to see samples geared towards operations on a very small set of types (i.e. Libraries, Library Commands) with tutorials explaining what the sample is trying to demonstrate. For example:
Library sample demostrates:
How to open a library.
How to close a library.
How to add items via approach A.
How to add items via approach B.
How to remove an item from a library.
How to remove an item from a library based on a specific criteria.
How to remove all items from a library.
Such samples would also demonstrate Adobe's idea of best practice - consistent code style, comments and error handling.
As Helmut25 posts in his thread "Tutorial for plug-in programming?" it would be good to see more step by step tutorials that don't just do a copy and paste but also explain clearly what is being done and why. You want to get into an Adobe developers head, understand their view of the universe and then apply what you've learned in your own projects.
Back onto error handling...
I've spent many a year doing Win32 programming (via C-style API, not MFC), so I'm used to using GetLastError() to find out why a function failed. Never really had reason to use SetLastError() and by and large avoided it. I think any API has to state what will happen when things go wrong (Microsoft's Win32 documentation is very good at this) and consequently you know how to write your code to account for such things.
One thing I like to do on standalone Win32/C/C++ applications is use a tool called AppVerifier, which allows you to throw various spanners into the works and see how your application copes. Shame there isn't something similar for testing plug-ins. I like to think that if InDesign crashes, it's not down to my code.
Regards,
APMABC -
Event Handler with Internal Loops
Hi...
I'm trying to update a basic program to handle control events more efficiently. The program needs to perform the following functions on start button press:
1) Import data file and parse instrument settings from multiple (X) rows
2) Perform loop with case for each row changing input settings, the read test equipment, and store data in new output data file
I've looked at producer/consumer example and the continuous measurement and logging example, but not sure if either (or none) of the following two options is the best way to handle the looping from the file...
A) Use events to trigger looping for all input cases within a consumer (I've had a problem with this due to not being able to terminate the loop within the consumer with an abort button)
B) Make the consumer only a single data acquisition and load loop inputs as queues and generate output queues to be handled by another parallel logging loop
Any advice?Hi bripple,
Based on what you've described above, a Producer/Consumer Design Pattern (Events) might work. There is a template for this design pattern that ships with LabVIEW which you can access by going to File > New > VI > From Template > Frameworks > Design Patterns. When the user clicks the start button on your front panel, you can queue up a command that will trigger your consumer loop to read the file and loop over each instrument setting. Within that loop, you should be able to queue up additional events corresponding to each instrument setting and reading.
In terms of error handling, you can conditionally stop a loop if you detect an error. If your user decides to push a button on the front panel to stop the entire process, you can use Enqueue Element at Opposite End to put a stop command at the beginning of the queue. When your consumer loop encounters this event, it can flush the queue and do any cleanup it needs to perform.
One additional thing to be cautious of is that queues can only handle one data type. Because of that, you may also want to consider a Queued Message Handler design pattern. This design pattern allows you to send both a command and data along with that command. I think that would be ideally situated for you since you could send a "Read Instrument" command along with the data for its settings. You can access this design pattern from within LabVIEW as well. If you have LabVIEW 2012 or LabVIEW 2013, see these instructions. The things I've said above also hold true for the Queued Message Handler as well.
Let me know if you have any questions or if this is helpful.
Regards,
Matthew B.
Applications Engineer
National Instruments -
Error Handling in BDC...Review code..
Hi Gurus,
I have made a BDC program to do call transaction for FV50...i AM NOT SURE ON HOW TO DO ERROR HANDLING IN THAT...TRIED TO DO SOMETHING BUT IT NEEDS LOT OF IMPROVEMENT...
CAN ONE YOU EXPERTS HELP ME IN THAT...I AM ATTACHING THE ENTIRE CODE..
REPORT zbdc_park_fv50.
DATA:
t_document_line_item_main LIKE bapiacgl09 OCCURS 100,
t_document_line_item_enhn LIKE bapiacextc OCCURS 100,
t_document_line_item_amnt LIKE bapiaccr09 OCCURS 100,
wa_document_header LIKE bapiache09,
wa_document_line_item_main LIKE bapiacgl09,
wa_document_line_item_enhn LIKE bapiacextc,
wa_document_line_item_amnt LIKE bapiaccr09.
DATA: BEGIN OF s_bdc_document_item_main,
v_HKONT LIKE ACGL_ITEM-HKONT,
v_SHKZG LIKE ACGL_ITEM-SHKZG,
v_SGTXT LIKE ACGL_ITEM-SGTXT,
v_WRBTR LIKE ACGL_ITEM-WRBTR,
v_WAERS LIKE ACGL_HEAD-WAERS,
v_PRCTR LIKE ACGL_ITEM-PRCTR,
v_YYLOB LIKE ACGL_ITEM-YYLOB,
v_YYCSG LIKE ACGL_ITEM-YYCSG,
END OF s_bdc_document_item_main.
DATA: t_bdc_document_item_main LIKE s_bdc_document_item_main OCCURS 0,
wa_bdc_document_item_main LIKE s_bdc_document_item_main.
DATA: t_bdcdata LIKE bdcdata OCCURS 0 with header line,
t_messages LIKE bdcmsgcoll OCCURS 0 with header line.
DATA: idx TYPE i,
ch3(2) TYPE n,
fname(40) TYPE c,
options TYPE ctu_params.
DATA: indate TYPE d,
intdate TYPE d,
var_SHKZG LIKE BSEG-SHKZG,
amount(13) type c.
DATA: w_textout LIKE t100-text.
*DATA: gd_update TYPE i,
gd_lines TYPE i.
CLEAR wa_document_header.
***FILL DOCUMENT HEADER***********
wa_document_header-obj_type = space. "
wa_document_header-obj_key = space.
wa_document_header-obj_sys = space.
wa_document_header-bus_act = 'RFBU'.
wa_document_header-username = 'samwil'.
wa_document_header-header_txt = 'TEST_BDC_PARK123'.
wa_document_header-comp_code = '1001'.
wa_document_header-doc_date = '20070817'.
wa_document_header-pstng_date = '20070817'.
CLEAR wa_document_header-trans_date.
CLEAR wa_document_header-fisc_year.
CLEAR wa_document_header-fis_period.
wa_document_header-doc_type = 'SY'.
wa_document_header-ref_doc_no = 'AAR1213'.
wa_document_header-ac_doc_no = space.
wa_document_header-obj_key_r = space.
wa_document_header-reason_rev = space.
wa_document_header-compo_acc = space.
wa_document_header-ref_doc_no_long = space.
wa_document_header-acc_principle = 'LGAP'.
wa_document_header-neg_postng = space.
wa_document_header-obj_key_inv = space.
wa_document_header-bill_category = space.
FILL LINE ITEMS *******************
CLEAR: wa_document_line_item_main, wa_document_line_item_enhn, wa_document_line_item_amnt.
Fill Main Portion Of Accounting Line Item
wa_document_line_item_main-itemno_acc = '1'. "Accounting Document Line Item Number
wa_document_line_item_main-gl_account = '2480001067'."HKONT - Account
wa_document_line_item_main-item_text = 'ITEM 2'. "SGTXT - Item Text
wa_document_line_item_main-doc_type = space. "BLART - Document Type
wa_document_line_item_main-comp_code = space. "BUKRS - Company Code
wa_document_line_item_main-pstng_date = '20080817'. "BUDAT - Posting Date
wa_document_line_item_main-alloc_nmbr = space. "ZUONR - Allocation Number
wa_document_line_item_main-costcenter = space. "KOSTL - Cost Center
wa_document_line_item_main-profit_ctr = '1999999'. "PRCTR - Profit Center
wa_document_line_item_main-de_cre_ind = 'D'. "NEWBS - Posting Key / Debit Credit Indicator
wa_document_line_item_main-trade_id = space. "RASSC - Company ID Of Trading Partner
Fill Amount Portion Of Accounting Line Item
wa_document_line_item_amnt-itemno_acc = '1'. "Accounting Document Line Item Number
wa_document_line_item_amnt-curr_type = '00'. "Currency Type
wa_document_line_item_amnt-currency = 'USD'. "WAERS - Currency Key
wa_document_line_item_amnt-amt_doccur = '100'. "WRBTR - Amount In Document Currency Type
Create Enhancement Portion Of Accounting Line Item
wa_document_line_item_enhn-field1+0(3) = '001'. "Line of Bus YYLOB
wa_document_line_item_enhn-field1+3(3) = '008'. "Customer Segm YYCSG
wa_document_line_item_enhn-field1+6(5) = space. "Product Group
wa_document_line_item_enhn-field1+11(2) = space. "Distribution Ch
wa_document_line_item_enhn-field1+13(4) = space. "Maturity Year
wa_document_line_item_enhn-field1+17(3) = space. "Insurance Type
wa_document_line_item_enhn-field1+20(4) = space. "Accident Year
wa_document_line_item_enhn-field1+24(6) = space. "Product
wa_document_line_item_enhn-field1+30(3) = space. "Source
wa_document_line_item_enhn-field1+33(22) = space. "DI Run Name
wa_document_line_item_enhn-field1+55(1) = space. "DI Run Type
wa_document_line_item_enhn-field1+56(5) = space. "DI Run Number
wa_document_line_item_enhn-field1+61(16) = space. "DI Journal ID
wa_document_line_item_enhn-field1+77(5) = space. "DI Journal Link
wa_document_line_item_enhn-field1+82(22) = space. "DI File Name
APPEND: wa_document_line_item_main TO t_document_line_item_main,
wa_document_line_item_enhn TO t_document_line_item_enhn,
wa_document_line_item_amnt TO t_document_line_item_amnt.
Fill Next Line Item #2
CLEAR: wa_document_line_item_main, wa_document_line_item_enhn, wa_document_line_item_amnt.
Fill Main Portion Of Accounting Line Item
wa_document_line_item_main-itemno_acc = '2'. "Accounting Document Line Item Number
wa_document_line_item_main-gl_account = '2480001067'."HKONT - Account
wa_document_line_item_main-item_text = 'ITEM 3'. "SGTXT - Item Text
wa_document_line_item_main-doc_type = space. "BLART - Document Type
wa_document_line_item_main-comp_code = space. "BUKRS - Company Code
wa_document_line_item_main-pstng_date = '20080817'. "BUDAT - Posting Date
wa_document_line_item_main-alloc_nmbr = space. "ZUONR - Allocation Number
wa_document_line_item_main-costcenter = space. "KOSTL - Cost Center
wa_document_line_item_main-profit_ctr = '1999999'. "PRCTR - Profit Center
wa_document_line_item_main-de_cre_ind = 'C'. "NEWBS - Posting Key / Debit Credit Indicator
wa_document_line_item_main-trade_id = space. "RASSC - Company ID Of Trading Partner
Fill Enhancement Portion Of Accounting Line Item
Fill Amount Portion Of Accounting Line Item
wa_document_line_item_amnt-itemno_acc = '2'. "Accounting Document Line Item Number
wa_document_line_item_amnt-curr_type = '00'. "Currency Type
wa_document_line_item_amnt-currency = 'USD'. "WAERS - Currency Key
wa_document_line_item_amnt-amt_doccur = '100'. "WRBTR - Amount In Document Currency Type
Create Enhancement Portion Of Accounting Line Item
wa_document_line_item_enhn-field1+0(3) = '001'. "Line of Bus YYLOB.
wa_document_line_item_enhn-field1+3(3) = '008'. "Customer Segm YYCSG
wa_document_line_item_enhn-field1+6(5) = space. "Product Group
wa_document_line_item_enhn-field1+11(2) = space. "Distribution Ch
wa_document_line_item_enhn-field1+13(4) = space. "Maturity Year
wa_document_line_item_enhn-field1+17(3) = space. "Insurance Type
wa_document_line_item_enhn-field1+20(4) = space. "Accident Year
wa_document_line_item_enhn-field1+24(6) = space. "Product
wa_document_line_item_enhn-field1+30(3) = space. "Source
wa_document_line_item_enhn-field1+33(22) = space. "DI Run Name
wa_document_line_item_enhn-field1+55(1) = space. "DI Run Type
wa_document_line_item_enhn-field1+56(5) = space. "DI Run Number
wa_document_line_item_enhn-field1+61(16) = space. "DI Journal ID
wa_document_line_item_enhn-field1+77(5) = space. "DI Journal Link
wa_document_line_item_enhn-field1+82(22) = space. "DI File Name
APPEND: wa_document_line_item_main TO t_document_line_item_main,
wa_document_line_item_enhn TO t_document_line_item_enhn,
wa_document_line_item_amnt TO t_document_line_item_amnt.
****FILL THE BDC TABLE*******************************************************
LOOP AT t_document_line_item_main INTO wa_document_line_item_main.
Move: wa_document_line_item_main-gl_account TO wa_bdc_document_item_main-v_HKONT,
wa_document_line_item_main-item_text TO wa_bdc_document_item_main-v_SGTXT,
wa_document_line_item_main-profit_ctr TO wa_bdc_document_item_main-v_PRCTR,
wa_document_line_item_main-de_cre_ind TO wa_bdc_document_item_main-v_SHKZG.
Read table t_document_line_item_amnt index sy-tabix into wa_document_line_item_amnt.
IF sy-subrc = 0.
Move : wa_document_line_item_amnt-currency TO wa_bdc_document_item_main-v_WAERS,
wa_document_line_item_amnt-amt_doccur TO wa_bdc_document_item_main-v_WRBTR.
ENDIF.
Read table t_document_line_item_enhn index sy-tabix into wa_document_line_item_enhn.
IF sy-subrc = 0.
Move : wa_document_line_item_enhn-field1+0(3) TO wa_bdc_document_item_main-v_YYLOB,
wa_document_line_item_enhn-field1+3(3) TO wa_bdc_document_item_main-v_YYCSG.
ENDIF.
APPEND wa_bdc_document_item_main TO t_bdc_document_item_main.
CLEAR: wa_bdc_document_item_main.
ENDLOOP. " BDC Table.
************************BDC PROGRAM**************************************************************
perform bdc_dynpro TABLES t_bdcdata using 'SAPLACHD' '1000'.
perform bdc_field TABLES t_bdcdata using 'BDC_CURSOR'
'BKPF-BUKRS'.
perform bdc_field TABLES t_bdcdata using 'BDC_OKCODE'
'=ENTR'.
perform bdc_field TABLES t_bdcdata using 'BKPF-BUKRS'
wa_document_header-comp_code.
perform bdc_dynpro TABLES t_bdcdata using 'SAPMF05A' '1001'.
perform bdc_field TABLES t_bdcdata using 'BDC_OKCODE'
'=PBBP'.
perform bdc_field TABLES t_bdcdata using 'ACGL_HEAD-BLDAT'
wa_document_header-doc_date.
perform bdc_field TABLES t_bdcdata using 'ACGL_HEAD-WAERS'
'USD'.
perform bdc_field TABLES t_bdcdata using 'ACGL_HEAD-BUDAT'
wa_document_header-pstng_date.
perform bdc_field TABLES t_bdcdata using 'ACGL_HEAD-XBLNR'
wa_document_header-ref_doc_no.
perform bdc_field TABLES t_bdcdata using 'ACGL_HEAD-BKTXT'
wa_document_header-header_txt.
perform bdc_field TABLES t_bdcdata using 'ACGL_HEAD-BLART'
wa_document_header-doc_type.
perform bdc_field TABLES t_bdcdata using 'BDC_CURSOR'
'ACGL_ITEM_GEN-GEN_CHAR2(02)'.
LOOP AT t_bdc_document_item_main INTO wa_bdc_document_item_main.
idx = idx + 1.
ch3 = idx.
CONCATENATE 'ACGL_ITEM-HKONT('ch3')' INTO FNAME.
perform bdc_field TABLES t_bdcdata using fname
wa_bdc_document_item_main-v_HKONT.
CONCATENATE 'ACGL_ITEM-SHKZG('ch3')' INTO FNAME.
IF wa_bdc_document_item_main-v_SHKZG = 'C'.
var_SHKZG = 'H'.
ELSEIF wa_bdc_document_item_main-v_SHKZG = 'D'.
var_SHKZG = 'S'.
ENDIF.
perform bdc_field TABLES t_bdcdata using fname
var_SHKZG.
CONCATENATE 'ACGL_ITEM-WRBTR('ch3')' INTO FNAME.
WRITE: wa_bdc_document_item_main-v_WRBTR to amount.
perform bdc_field TABLES t_bdcdata using FNAME
wa_bdc_document_item_main-v_WRBTR.
amount.
CONCATENATE 'ACGL_ITEM-SGTXT('ch3')' INTO FNAME.
perform bdc_field TABLES t_bdcdata using FNAME
wa_bdc_document_item_main-v_SGTXT.
CONCATENATE 'ACGL_ITEM-PRCTR('ch3')' INTO FNAME.
perform bdc_field TABLES t_bdcdata using FNAME
wa_bdc_document_item_main-v_PRCTR.
CONCATENATE 'ACGL_ITEM_GEN-GEN_CHAR1('ch3')' INTO FNAME.
perform bdc_field TABLES t_bdcdata using FNAME
wa_bdc_document_item_main-v_YYLOB.
CONCATENATE 'ACGL_ITEM_GEN-GEN_CHAR2('ch3')' INTO FNAME.
perform bdc_field TABLES t_bdcdata using FNAME
wa_bdc_document_item_main-v_YYCSG.
options-dismode = 'A'.
options-nobinpt = 'X'.
endloop.
CALL TRANSACTION 'FV50' USING t_bdcdata MESSAGES INTO
t_messages OPTIONS FROM options.
*if sy-subrc = 0.
Retrieve error messages
LOOP AT t_messages WHERE msgtyp = 'E'.
Builds actual message based on info returned from Call transaction
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
msgid = t_messages-msgid
msgnr = t_messages-msgnr
msgv1 = t_messages-msgv1
msgv2 = t_messages-msgv2
msgv3 = t_messages-msgv3
msgv4 = t_messages-msgv4
IMPORTING
message_text_output = w_textout.
ENDLOOP.
Start new screen
FORM bdc_dynpro TABLES it_bdcdata STRUCTURE bdcdata USING program
dynpro.
DATA: wa_bdcdata TYPE bdcdata.
wa_bdcdata-program = program.
wa_bdcdata-dynpro = dynpro.
wa_bdcdata-dynbegin = 'X'.
APPEND wa_bdcdata TO it_bdcdata.
ENDFORM. "BDC_DYNPRO
Insert field
FORM bdc_field TABLES it_bdcdata STRUCTURE bdcdata USING fnam fval.
DATA: wa_bdcdata TYPE bdcdata.
IF fval <> space.
CLEAR wa_bdcdata.
wa_bdcdata-fnam = fnam.
wa_bdcdata-fval = fval.
APPEND wa_bdcdata TO it_bdcdata.
ENDIF.
ENDFORM. "BDC_FIELD
Title was edited by:
Alvaro Tejada GalindoHI,
The code looks ok...
take a internal table for messages.
data : begin of itab occurs 0,
message(100) type c,
end of itab.
put this after
Retrieve error messages
LOOP AT t_messages WHERE msgtyp = 'E'.
Builds actual message based on info returned from Call transaction
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
msgid = t_messages-msgid
msgnr = t_messages-msgnr
msgv1 = t_messages-msgv1
msgv2 = t_messages-msgv2
msgv3 = t_messages-msgv3
msgv4 = t_messages-msgv4
IMPORTING
message_text_output = w_textout.
<b>itab-message = w_textout.
append itab</b>.
ENDLOOP. -
I am not very good at error handling in APEX. Currently I have a problem where, if a user tries to insert a row in a table and there is already a row with the same primary key, they get an APEX error message with a little OK button. When they press the OK, it loops right back to the same error message. The only way out of this is to use the browser back button drop down and go back two pages. Note: the page that generates the error is a page that automatically submits itself via a simple Javascript. So, how do I check to see if there is going to be a primary key constraint error, display a message and go back to the page where the user choose the data that caused the duplicate key error? The error is generated out of the Automatic Row Processing process when the page is submitted.
Edited by: DaleB on Feb 17, 2009 6:33 AMHi,
I think it would depend on the sequence of events that are gone through to create the record. I have done something similar where the user makes one or more selections on page items, then clicks on a Day Link in a calendar - this passes values (through a URL rather than a Submit) to a second page which automatically submits the page to create a new record to show in the calendar.
I assume that your user does something on, say, Page 1, which is submitted and transfers to, say, Page 2, which automatically submits to create record? Or is this passed by a URL as in my case?
If you submit Page 1 first, you could perform validation on Page 1. If you pass the items using a URL, you could have a conditional branch on Page 2 that is in the "Before Header" branch point that branches to a page that shows an error message and provides a button to return to Page 1 - the insert, therefore, never takes place as the page is never loaded.
Andy -
Page Error handling question..
Using APEX 4.1.1.. Hosted instance.. I am testing various error handling functions (Oracle's standard one from documentation and others). I have a page with a standard report, I have defined the page to have an associated error handling function. On the report I have a calculated column that should error out due to a division by 0 error..
Now what I had thought was, the page would handle the error more gracefully than previous version, in that it would show the custom error message I define in the constraints table...
Is there a section of the documentation I am missing that shows at what point the error handling function kicks in and where we need to invoke it otherwise?
Thank you,
Tony Miller
Dallas, TXInteresting. Had never considered this aspect.
Just did a couple of tests - so it must only come into play from the PL/SQL engine.
Created an sql report:
select floor(dbms_random.value(1,10))/0 num
from dual
connect by level <= 10But the error function never gets hit.
begin
for i in (select floor(dbms_random.value(1,10))/0 num
from dual
connect by level <= 10) loop
htp.p(i.num);
end loop;
end;Function gets hit.
Just looking at the docs, there doesn't appear to be any indication of processing point.
But from Patrick's blog:
This includes errors raised by validation, process, … and all errors raised by the Application Express engine itself.http://www.inside-oracle-apex.com/apex-4-1-error-handling-improvements-part-1/
I guess an SQL report isn't considered as an 'all errors raised by the apex engine'. -
Error handler for ORA-29283 - not working
I am running Oracle 9.2.0.4 on HP-UX.
I have a stored procedure which reads a text file. I have set up an execption for error code ORA-29283 (invalid file operation). When I test my procedure (by not having the file to read) my exception handler is bypassed for a general exception error and my procedure terminates.
here's parts of my code:
Declare
file_not_found EXCEPTION;
PRAGMA EXCEPTION_INIT (file_not_found, -29283);
BEGIN
nochourly_file := UTIL_FILE.fopen('/mydirectory','myfile.txt','R');
Loop
begin
UTL_FILE.get_line(nochourly_file, sbuffer);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
GOTO end_of_file;
WHEN file_not_found
THEN
DBMS_OUTPUT.put_line ('Invalid File Operation - file not found');
skip_last_hour_processed;
GOTO end_of_file;
WHEN OTHERS
THEN
err_num := SQLCODE;
err_msg := SUBSTR (SQLERRM, 1, 100);
DBMS_OUTPUT.put_line ('Error ' || TO_CHAR (err_num));
DBMS_OUTPUT.put_line (err_msg);
DBMS_OUTPUT.put_line (sbuffer);
RAISE;
EXIT;
END;
===============
When this fails I expect to see the message
"Invalid file operation - file not found"
which indicates my exception handler was processed.
Instead I see:
SQL> @$HOME/newhourly_dly
Begin processing at 20060627154321
nlasthourprocessed:20060627100000
Last Hour Processed is 20060627100000
BEGIN noc_hourly_daily_load; END;
ERROR at line 1:
ORA-29283: invalid file operation
ORA-06512: at "SYS.UTL_FILE", line 449
ORA-29283: invalid file operation
ORA-06512: at "HNS.NOC_HOURLY_DAILY_LOAD", line 374
ORA-06512: at line 1
Elapsed: 00:00:00.05
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Can you explain:
1) what generated the error message since
a. it wasn't my exception handler and
b. it wasn't the "WHEN OTHERS"
2) Why isn't my error handler working?
Please advise.
Thank youHello
Not sure why your exception is being ignored but usually, to be able to handle the UTL_FILE exceptions, you need to explicitly code for each exception declared in the UTL_FILE package i.e.
EXCEPTION
WHEN utl_file.invalid_path THEN
--Do something
WHEN utl_file.invalid_mode THEN
--Do something
WHEN utl_file.invalid_filehandle THEN
--Do something
WHEN utl_file.invalid_operation THEN
--Do something
WHEN utl_file.read_error THEN
--Do something
WHEN utl_file.write_error THEN
--Do something
WHEN utl_file.internal_error THEN
--Do something
END;HTH
David -
3.2 to 4.1 Upgrade - Error Handling for Unavailable Database Links
Hi,
I'm having a 3.2 -> 4.1 upgrade issue related to error handling for failed database links.
I have a conditional Exists button on a page that has a SQL query to linked tables. However, for the 10 minutes every day where the target of the database link is getting a cold backup, the query fails. In the old 3.2 apex I simply got an error inside the region where the button is located but otherwise the page was still visible:
"Invalid exists/not exists condition: ORA-02068: following severe error from MYDBLINK ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist"
However, in apex 4.1.0.00.32 I get the following unhandled error, and clicking "OK" takes me to the edit page when logged in as developer.
i.e., the page can't be run at all while the database links are failing in this one region.
Error Error processing condition.
ORA-12518: TNS:listener could not hand off client connection
Technical Info (only visible for developers):
is_internal_error: true
apex_error_code: APEX.CONDITION.UNHANDLED_ERROR
ora_sqlcode: -12518
ora_sqlerrm: ORA-12518: TNS:listener could not hand off client connection
component.type: APEX_APPLICATION_PAGE_REGIONS
component.id: 4
component.name: Current Alerts
error_backtrace:
ORA-06512: at "SYS.WWV_DBMS_SQL", line 1041
ORA-06512: at "APEX_040100.WWV_FLOW_DYNAMIC_EXEC", line 687
ORA-06512: at "APEX_040100.WWV_FLOW_CONDITIONS", line 272
General users see this:
Error Error processing condition.
ORA-01034: ORACLE not available ORA-02063: preceding line from MYDBLINK
clicking "OK" takes user to another page, not sure how apex decides which, but not a concern at the moment.
I've done a search and read the page http://www.inside-oracle-apex.com/apex-4-1-error-handling-improvements-part-1/ but the new apex error handling isn't clear to me, and I don't know if the apex_error_handling_example provided on that page would be applicable to this situation.Thanks Patrick.
The PL/SQL Function Body returning boolean condition with:
begin
for l_check in (
SELECT 1
FROM myview@MYDBLINK
WHERE ... ) loop
return true;
end loop;
return false;
exception when others then
sys.htp.p('Invalid exists/not exists condition: ' || sys.htf.escape_sc(sqlerrm));
return false;
end; Resulted in a similar issue:
Error Error processing condition.
ORA-04052: error occurred when looking up remote object MYLINKUSER.myview@MYDBLINK
ORA-00604: error occurred at recursive SQL level 3
ORA-01033: ORACLE initialization or shutdown in progress
ORA-02063: preceding line from MYDBLINK
Technical Info (only visible for developers)
is_internal_error: true
apex_error_code: APEX.CONDITION.UNHANDLED_ERROR
ora_sqlcode: -4052
ora_sqlerrm: ORA-04052: error occurred when looking up remote object MYLINKUSER.myview@MYDBLINK
ORA-00604: error occurred at recursive SQL level 3
ORA-01033: ORACLE initialization or shutdown in progress
ORA-02063: preceding line from MYDBLINK
component.type: APEX_APPLICATION_PAGE_REGIONS
component.id: 4
component.name: Current Alerts
error_backtrace:
ORA-06512: at "SYS.WWV_DBMS_SQL", line 904
ORA-06512: at "APEX_040100.WWV_FLOW_DYNAMIC_EXEC", line 588
ORA-06512: at "APEX_040100.WWV_FLOW_CONDITIONS", line 148However, I created a view with the same query:
CREATE OR REPLACE VIEW v_localview (ALERT_1)
AS
SELECT 1
FROM myview@MYDBLINK ...then change the condition to look at the local view:
begin
for l_check in (
select alert_1 from v_localview ) loop
return true;
end loop;
return false;
exception when others then
sys.htp.p('Invalid exists/not exists condition: ' || sys.htf.escape_sc(sqlerrm));
return false;
end;As a view is simply a query I'm surprised this should make any difference but it now looks similar to the 3.2 error, inside the region, when the linked database gets its morning cold backup, and this is fine:
Invalid exists/not exists condition: ORA-12518: TNS:listener could not hand off client connection -
Hi,
I am reading continuous data from a RS232 interface. During the communication it might can be that the remote station is powered off due to maintenance work. How can I determine the connection lost? The error out of the function 'Number of Bytes at Port' and 'Read Serial' is empty. Do I have to set a property to enable error handling? What I'm doing wrong? I've attached a screenshot of a test vi where independent of connecting the RS232 cable no error code is displayed.
Kind Regards,
Joachim
Solved!
Go to Solution.
Attachments:
TEMP_TEST_RS232.vi 13 KBThat's what the timeout is good for.
You didn't specify if you poll the data (send a query command to the device and read the answer) or if the device is pushing the data (sending each ?? second(s) some byte) .
However, whenever the connection is down, you woun't get any bytes back .
You can use the build in timeout and try to read 1 or more byte or build your own timeout in the polling loop with 'Number of Bytes at Port' ...
Greetings from Germany
Henrik
LV since v3.1
“ground” is a convenient fantasy
'˙˙˙˙uıɐƃɐ lɐıp puɐ °06 ǝuoɥd ɹnoʎ uɹnʇ ǝsɐǝld 'ʎɹɐuıƃɐɯı sı pǝlɐıp ǝʌɐɥ noʎ ɹǝqɯnu ǝɥʇ' -
Is this a qucik and satisfactory method for CLD error handling? (see image)
http://i.imgur.com/IiI8D1w.png
with reference to: http://i.imgur.com/TyNVWQX.png (from success package document)
Is this too simple an error handler setup? Assuming non-catastrophic errors are taken care of before leaving any case in my qsm? An error is only acceptable during debugging isnt it? (unless instructed by requirements?)
I'm trying to think of ways to save some time as I've been working so much I let my test date creep up on me...
Thanks
Solved!
Go to Solution.PatLyons wrote:
Is this too simple an error handler setup?
In the real world, yes. For the CLD, that is a minimum to get the points. Just throw down the Simple Error Handler to show the error dialog and you have "handled the error". If the spec does not say how to handle the error, stop the loop(s) and show the error dialog. If you are given a spec of how to handle the error, do whatever you are told.
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines -
How to take control back from service error handler in osb
I am using osb to send data to multiple services at the same time.since x query is a procedural language if any single operation fails the flow goes to service error handler which calls a BPEL webservice and logs the error in a database but the control doesnt comes back to my code I have tried everything including RESUME,REPLY operations but all in vain similarly i cannot use service callout call to my business service because its not allowing to select my BPEL wsdl operation
If your statement "the control doesnt comes back to my code" means you expect that your xquery will continue in processing than your expectations are just too high. :-)
Resume action is supposed to resume the next action in the message flow. It means the action that follows the action which caused an error.
Maybe you are looking for
-
Can't delete songs from iPod Touch
My ipod touch is displaying songs that don't display in my playlist when I sync it with the computer, about 20 random songs that I don't even recall downloading....and it won't let me delete the individual songs from the ipod by sliding and clicking
-
When should an Account be created
Hello, We are in a stand still with the business decision of when to create an Account. Reviewing your definition of an account as follows, "Accounts are generally companies that you do business with, but you can also track partners and competitors a
-
HT4796 Where are the files after migration?
I used the Migration to transfer files from my old PC to my new MacBook Pro. Where can I find the files on the MacBook Pro?
-
ICloud Photo Library taking up too much space
I am using iCloud Photo library, and noticed that it was taking up too much of my iCloud memory. I have 4 photos and no videos, and that uses around 300 MB of storage. What can I do to change this? Is this a bug?
-
Guys, The following configuration for authentication and authorization doesn't work on 6513 alone. But same configuration is working on 100+ CAT switches. I have verified that ACS server is reachable from 6513 and entry is available for 6513 on ACS s