{"id":394,"date":"2010-02-09T12:51:07","date_gmt":"2010-02-09T16:51:07","guid":{"rendered":"https:\/\/clarionsharp.com\/blog\/?p=394"},"modified":"2010-02-09T12:51:07","modified_gmt":"2010-02-09T16:51:07","slug":"lastchancehook","status":"publish","type":"post","link":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/","title":{"rendered":"LastChanceHook"},"content":{"rendered":"<p>Geoff Thomson from Capesoft asked me about an example on how to override the RTL&#8217;s internal exception handler.\u00a0\u00a0 I think this is a topic that is likely of interest to many Clarion developers and warrants an example, so here we go.<\/p>\n<h3><span style=\"color: #ff6600;\">Overview<\/span><\/h3>\n<p>PROP:LastChanceHook is a write-only SYSTEM property, which allows you to specify your own function that will be invoked if an exception occurs. The hook  function allows you to display information about the exception and choose one of the following actions:<\/p>\n<ul>\n<li style=\"font-size: 9pt;\"> Continue execution of the  thread where the exception occurred (unless the exception is fatal)<\/li>\n<li style=\"font-size: 9pt;\"> Stop the thread (or the entire process if the exception occurred in the main process thread) without  invoking the RTL&#8217;s internal exception handler<\/li>\n<li style=\"font-size: 9pt;\"> Invoke the RTL&#8217;s internal exception handler<\/li>\n<\/ul>\n<ul><\/ul>\n<p style=\"margin-top: 6pt; margin-bottom: 6pt;\">This  allows you to catch an exception, and if it is non-fatal you can allow your end users to continue executing your program even when an exception has occurred  in one of its threads.<\/p>\n<h2 style=\"margin-top: 6pt; margin-bottom: 6pt;\"><span style=\"color: #ff6600;\"><br \/>\n<\/span><\/h2>\n<h3><span style=\"color: #ff6600;\"> How It Works<\/span><\/h3>\n<p>Your function, which you assign to the SYSTEM{PROP:LastChanceHook} property has to have a prototype of:<\/p>\n<p>HookProc (*ICWExceptionInfo),LONG<\/p>\n<p>The ICWExceptionInfo parameter is an interface declared in <strong>CWEXCPT.INT<\/strong> which you&#8217;ll find in your .Libsrc folder.<\/p>\n<p>The result returned by the hooked function is evaluated as follows:<\/p>\n<ul>\n<li>If the result is equal to Zero, the RTL executes its own internal exception handler dialog to show information about the exception and subsequently perform the action chosen by the end user.<\/li>\n<li>If a Positive number is returned, the RTL stops the thread (or the entire process if the exception occurred in the main process thread) without invoking the RTL exception handler.<\/li>\n<li>If a Negative number is returned, the program will try to continue from the point of the exception. Note, if the exception is non-continuable, this result is ignored and treated as equal to Zero.<\/li>\n<\/ul>\n<p>So in our example we start with this code:<\/p>\n<p><code><br \/>\nPROGRAM<\/code><\/p>\n<p><strong>INCLUDE(&#8216;CWEXCPT.INT&#8217;),ONCE<\/strong><\/p>\n<p style=\"padding-left: 30px;\">MAP<br \/>\nTest (LONG,LONG)<br \/>\n<strong> Hook (*ICWExceptionInfo),LONG<\/strong><br \/>\nHEX  (LONG),STRING,PRIVATE<br \/>\nMODULE(&#8221;)<br \/>\nMessageBox (UNSIGNED, CONST *CSTRING, CONST *CSTRING, UNSIGNED),SIGNED,PROC,PASCAL,NAME(&#8216;MessageBoxA&#8217;)<br \/>\nEND<\/p>\n<p style=\"padding-left: 30px;\">END<\/p>\n<p>MB_ICONHAND EQUATE(00000010h)<\/p>\n<p style=\"padding-left: 30px;\">CODE<br \/>\n<strong>SYSTEM{PROP:LastChanceHook} = ADDRESS (Hook)<\/strong><br \/>\nTest (10, 0)\u00a0 ! causes an exception<br \/>\nRETURN<\/p>\n<p>In this example the Procedure named &#8220;Hook&#8221; is assigned as our exception handler. That&#8217;s the only Procedure we are concerned with, the others are just there to help make the example work by 1) causing an exception and 2) informing the user about the exception. Next we have:<\/p>\n<p><code><br \/>\n! ------------------------------------------------------------------------------<\/code><\/p>\n<p><strong>Hook  PROCEDURE (*ICWExceptionInfo info)<\/strong><\/p>\n<p>S       CSTRING(1024)<br \/>\nCaption CSTRING(256)<\/p>\n<p style=\"padding-left: 30px;\">CODE<br \/>\nIF info &amp;= NULL<br \/>\nRETURN 0<br \/>\nEND<\/p>\n<p style=\"padding-left: 30px;\">Caption = &#8216;Exception &#8216; &amp; HEX (<strong>info.ExceptionCode()<\/strong>) &amp; &#8216; at &#8216; &amp; HEX (<strong>info.ExceptionAddress()<\/strong>)<br \/>\nS = &#8216;Registers&#8217; &amp; |<br \/>\n&#8216;&lt;13,10&gt;EAX=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_EAX)) &amp; |<br \/>\n&#8216;       EBX=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_EBX)) &amp; |<br \/>\n&#8216;       ECX=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_ECX)) &amp; |<br \/>\n&#8216;       EDX=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_EDX)) &amp; |<br \/>\n&#8216;&lt;13,10&gt;ESI=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_ESI)) &amp; |<br \/>\n&#8216;       EDI=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_EDI)) &amp; |<br \/>\n&#8216;       ESP=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_ESP)) &amp; |<br \/>\n&#8216;       EBP=&#8217; &amp; HEX (info.Register (i386_Register:Reg32_EBP)) &amp; |<br \/>\n&#8216;&lt;13,10,13,10&gt;Current thread is being terminated&#8217;<\/p>\n<p style=\"padding-left: 30px;\">MessageBox (0, S, Caption, MB_ICONHAND)<br \/>\nRETURN 1\u00a0\u00a0\u00a0\u00a0\u00a0 ! a positive value signals the RTL to kill the thread<\/p>\n<p>! &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p><strong>Test  PROCEDURE (LONG a, LONG b)<\/strong><\/p>\n<p style=\"padding-left: 30px;\">CODE<br \/>\na %= b<\/p>\n<p>! &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p><strong>HEX  PROCEDURE (LONG A)<\/strong><\/p>\n<p style=\"padding-left: 30px;\">i       UNSIGNED,AUTO<br \/>\nS       STRING(8),AUTO<br \/>\nDIGITS  STRING(&#8216;0123456789ABCDEF&#8217;),STATIC<\/p>\n<p style=\"padding-left: 30px;\">CODE<br \/>\ni = SIZE(S)<\/p>\n<p style=\"padding-left: 30px;\">LOOP WHILE i &lt;&gt; 0<br \/>\nS [i] = DIGITS [BAND (A, 0Fh) + 1]<br \/>\nA     = BSHIFT (A, -4)<br \/>\ni    -= 1<br \/>\nEND<\/p>\n<p style=\"padding-left: 30px;\">RETURN S<\/p>\n<p>! &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n<br \/><\/br><br \/>\nThese first two lines of code assign our exception handler function and then call the Test procedure that raises an exception:<\/p>\n<p><strong>SYSTEM{PROP:LastChanceHook} = ADDRESS (Hook)<\/strong><br \/>\nTest (10, 0)\u00a0 ! causes an exception<\/p>\n<p>The exception is trapped and we show the result in a MessageBox which looks like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-427\" title=\"customexception\" src=\"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2010\/02\/customexception.png\" alt=\"customexception\" width=\"560\" height=\"204\" \/><\/p>\n<p>our <strong>Hook  PROCEDURE (*ICWExceptionInfo info)<\/strong> uses the methods in the interface to show the exception code, its address, and the values of the registers at the time of the exception. And remember we said that:<\/p>\n<p>&#8220;If a Positive number is returned, the RTL stops the thread (or the entire process if the exception occurred in the main process thread) without invoking the RTL exception handler.&#8221;<\/p>\n<p>in our example our Hook PROCEDURE does a &#8220;RETURN <strong>1<\/strong>&#8221; and since we are running on the main thread then immediately after the MessageBox is displayed and the user presses the OK button the program itself is terminated.<\/p>\n<p>In a future article we&#8217;ll show you how to easily display the callstack so that your end-user can tell you exactly which procedure caused the exception. And we&#8217;ll be adding an option to the templates so that you can do the same with a couple of mouse clicks. You can download the source code for this example <a href=\"http:\/\/www.clarionsharp.com\/files\/PropLastChanceHook.zip\">from this link<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Geoff Thomson from Capesoft asked me about an example on how to override the RTL&#8217;s internal exception handler.\u00a0\u00a0 I think this is a topic that is likely of interest to many Clarion developers and warrants an example, so here we go. Overview PROP:LastChanceHook is a write-only SYSTEM property, which allows you to specify your own &hellip; <a href=\"https:\/\/clarionsharp.com\/blog\/lastchancehook\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">LastChanceHook<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-394","post","type-post","status-publish","format-standard","hentry","category-clarion-7"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>LastChanceHook - Clarion<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/clarionsharp.com\/blog\/lastchancehook\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"LastChanceHook - Clarion\" \/>\n<meta property=\"og:description\" content=\"Geoff Thomson from Capesoft asked me about an example on how to override the RTL&#8217;s internal exception handler.\u00a0\u00a0 I think this is a topic that is likely of interest to many Clarion developers and warrants an example, so here we go. Overview PROP:LastChanceHook is a write-only SYSTEM property, which allows you to specify your own &hellip; Continue reading LastChanceHook &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/clarionsharp.com\/blog\/lastchancehook\/\" \/>\n<meta property=\"og:site_name\" content=\"Clarion\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/softvelocity\/\" \/>\n<meta property=\"article:published_time\" content=\"2010-02-09T16:51:07+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2010\/02\/customexception.png\" \/>\n<meta name=\"author\" content=\"rzaunere\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"rzaunere\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/\"},\"author\":{\"name\":\"rzaunere\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#\\\/schema\\\/person\\\/b90e860529aea05ad064cf2687697ce3\"},\"headline\":\"LastChanceHook\",\"datePublished\":\"2010-02-09T16:51:07+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/\"},\"wordCount\":825,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/02\\\/customexception.png\",\"articleSection\":[\"Clarion 7\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/\",\"url\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/\",\"name\":\"LastChanceHook - Clarion\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/02\\\/customexception.png\",\"datePublished\":\"2010-02-09T16:51:07+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#primaryimage\",\"url\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/02\\\/customexception.png\",\"contentUrl\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/02\\\/customexception.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/lastchancehook\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"LastChanceHook\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/\",\"name\":\"Clarion\",\"description\":\"Deliver your software on time, every time\",\"publisher\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#organization\",\"name\":\"SoftVelocity\",\"url\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/svlogonew57.png\",\"contentUrl\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/svlogonew57.png\",\"width\":221,\"height\":57,\"caption\":\"SoftVelocity\"},\"image\":{\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/softvelocity\\\/\",\"https:\\\/\\\/www.youtube.com\\\/user\\\/SoftVelocity\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/#\\\/schema\\\/person\\\/b90e860529aea05ad064cf2687697ce3\",\"name\":\"rzaunere\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/91d95e38759c411d27f646b60da7f4769ce91e87b484669af240e51c729b1e7c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/91d95e38759c411d27f646b60da7f4769ce91e87b484669af240e51c729b1e7c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/91d95e38759c411d27f646b60da7f4769ce91e87b484669af240e51c729b1e7c?s=96&d=mm&r=g\",\"caption\":\"rzaunere\"},\"url\":\"https:\\\/\\\/clarionsharp.com\\\/blog\\\/author\\\/rzaunere\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"LastChanceHook - Clarion","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/","og_locale":"en_US","og_type":"article","og_title":"LastChanceHook - Clarion","og_description":"Geoff Thomson from Capesoft asked me about an example on how to override the RTL&#8217;s internal exception handler.\u00a0\u00a0 I think this is a topic that is likely of interest to many Clarion developers and warrants an example, so here we go. Overview PROP:LastChanceHook is a write-only SYSTEM property, which allows you to specify your own &hellip; Continue reading LastChanceHook &rarr;","og_url":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/","og_site_name":"Clarion","article_publisher":"https:\/\/www.facebook.com\/softvelocity\/","article_published_time":"2010-02-09T16:51:07+00:00","og_image":[{"url":"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2010\/02\/customexception.png","type":"","width":"","height":""}],"author":"rzaunere","twitter_card":"summary_large_image","twitter_misc":{"Written by":"rzaunere","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/#article","isPartOf":{"@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/"},"author":{"name":"rzaunere","@id":"https:\/\/clarionsharp.com\/blog\/#\/schema\/person\/b90e860529aea05ad064cf2687697ce3"},"headline":"LastChanceHook","datePublished":"2010-02-09T16:51:07+00:00","mainEntityOfPage":{"@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/"},"wordCount":825,"commentCount":3,"publisher":{"@id":"https:\/\/clarionsharp.com\/blog\/#organization"},"image":{"@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/#primaryimage"},"thumbnailUrl":"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2010\/02\/customexception.png","articleSection":["Clarion 7"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/clarionsharp.com\/blog\/lastchancehook\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/","url":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/","name":"LastChanceHook - Clarion","isPartOf":{"@id":"https:\/\/clarionsharp.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/#primaryimage"},"image":{"@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/#primaryimage"},"thumbnailUrl":"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2010\/02\/customexception.png","datePublished":"2010-02-09T16:51:07+00:00","breadcrumb":{"@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/clarionsharp.com\/blog\/lastchancehook\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/#primaryimage","url":"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2010\/02\/customexception.png","contentUrl":"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2010\/02\/customexception.png"},{"@type":"BreadcrumbList","@id":"https:\/\/clarionsharp.com\/blog\/lastchancehook\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/clarionsharp.com\/blog\/"},{"@type":"ListItem","position":2,"name":"LastChanceHook"}]},{"@type":"WebSite","@id":"https:\/\/clarionsharp.com\/blog\/#website","url":"https:\/\/clarionsharp.com\/blog\/","name":"Clarion","description":"Deliver your software on time, every time","publisher":{"@id":"https:\/\/clarionsharp.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/clarionsharp.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/clarionsharp.com\/blog\/#organization","name":"SoftVelocity","url":"https:\/\/clarionsharp.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/clarionsharp.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2019\/03\/svlogonew57.png","contentUrl":"https:\/\/clarionsharp.com\/blog\/wp-content\/uploads\/2019\/03\/svlogonew57.png","width":221,"height":57,"caption":"SoftVelocity"},"image":{"@id":"https:\/\/clarionsharp.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/softvelocity\/","https:\/\/www.youtube.com\/user\/SoftVelocity"]},{"@type":"Person","@id":"https:\/\/clarionsharp.com\/blog\/#\/schema\/person\/b90e860529aea05ad064cf2687697ce3","name":"rzaunere","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/91d95e38759c411d27f646b60da7f4769ce91e87b484669af240e51c729b1e7c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/91d95e38759c411d27f646b60da7f4769ce91e87b484669af240e51c729b1e7c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/91d95e38759c411d27f646b60da7f4769ce91e87b484669af240e51c729b1e7c?s=96&d=mm&r=g","caption":"rzaunere"},"url":"https:\/\/clarionsharp.com\/blog\/author\/rzaunere\/"}]}},"_links":{"self":[{"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/posts\/394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/comments?post=394"}],"version-history":[{"count":0,"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/posts\/394\/revisions"}],"wp:attachment":[{"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/media?parent=394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/categories?post=394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/clarionsharp.com\/blog\/wp-json\/wp\/v2\/tags?post=394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}