Skip to main content
Bridgette.Is.Enthusiastic
Inspiring
July 1, 2024
Answered

JS script how do I correctly use try...catch() for error handling?

  • July 1, 2024
  • 1 reply
  • 2099 views

Hello again! I made a similar post a few days ago that helped me solve one problem, but unfortunately it created another, so I'm back.

 

Quick background: I have modified a script created by Kasyan (found here) that finds tags and replaces them with images. The main changes I made now have the script create an anchored text frame where the tag is found, find and insert the image file inline in the new text frame, and then grab the "Description" from the xmp link and insert it as text after the image.

 

The problem: The script runs beautifully so long as it is able to find the metadata it is looking for. I have tried to use try...catch() to look for the linkXmp.description, but I think I fundementally don't understand what to put in the "catch" area. I want it to just tell the script that the description is null so I can later use "else" to put a placeholder in the caption text frame.

(This might not be the best way to handle this - the image files that are returning empty definitely have the metadata there when I look at them in Bridge. Would you recommend a different way of grabbing the metadata, or error handling if it can't be found?)

 

What I'm trying: here is the small snippet that is causing problems for me:

try {
	//get XMP Description
	imgDescription = imgPath.linkXmp.description;
}
catch (err){
	if (debug) $.writeln(err.message + ", line: " + err.line);			
}
//add caption contents from XMP Description
finally{
	if (imgDescription != null){
		captionInsPts.contents = "\r" + imgDescription;
	}
	else {
		captionInsPts.contents = "\r Description metadata not available";
	}
}

 

The code: below is the meat of the script where I made most of the changes. Most of the script outside of this section is the same as the original script by Kasyan, linked above so you can compare. I have attached the full script in case the problem cannot be found in the excerpt below:

if(imgFile != null) {

	//remove figure tag from text
	foundItem.remove();
	story.recompose();	

	//create caption frame
	imgCaption = story.insertionPoints[insPtIndex].textFrames.add();

	//set position and size of the caption frame
	imgCaption.geometricBounds = [imgCaption.geometricBounds[0], 
		imgCaption.geometricBounds[1], 
		imgCaption.geometricBounds[2], 
		imgCaption.geometricBounds[1] + maxWidth ];

	//insert container for image file
	container = imgCaption.insertionPoints[0].rectangles.add();
	currentStyle = container.appliedObjectStyle;
	captionInsPts = imgCaption.insertionPoints[-1]

	//set position and size of image file container
	gb = container.geometricBounds;
	width = gb[3] - gb[1];
	height = gb[2] - gb[0];

	container.geometricBounds = [container.geometricBounds[0], 
		container.geometricBounds[1], 
		gb[0] + maxHeight,
		gb[3] ];

	container.geometricBounds = [container.geometricBounds[0], 
		container.geometricBounds[1], 
		container.geometricBounds[2], 
		container.geometricBounds[1] + maxWidth ];

	//place figure image
	img = container.place(imgFile)[0];

	//set frame fitting options for image
	if (set.fitOption > 1) { 
		container.fit(fitOptions[set.fitOption - 2]);
		if (set.fitFrameToContents && (set.fitOption == 6 || set.fitOption == 7)) {
			container.fit(FitOptions.FRAME_TO_CONTENT);
		}
	}

	var imgPath = img.itemLink;
	//find and place metadata as caption
	try {
		//get XMP Description
		imgDescription = imgPath.linkXmp.description;
	}
	catch (err){
		if (debug) $.writeln(err.message + ", line: " + err.line);
	}

	//add caption contents from XMP Description
	finally{
		if (imgDescription != null){
			captionInsPts.contents = "\r" + imgDescription;
		}
		else {
			captionInsPts.contents = "\r Description metadata not available";
		}
	}

	//finalize styles
	imgCaption.applyObjectStyle(currentStyle);
	imgCaption.clearObjectStyleOverrides ();	
	container.applyObjectStyle(app.activeDocument.objectStyleGroups.itemByName("Figures"));
	container.clearObjectStyleOverrides ();

	count++;
}
else {
	logErrArr.push(figureTagID + " - the file doesn't exist." + " - page " + ((pageNumber != null) ?  pageNumber : "N/A"));
}

 

This topic has been closed for replies.
Correct answer m1b

when I add that line of code in where you specified, I get an alert that says "Critical error: The requested action could not be completed because the object no longer exists., line: 142" which is referring this line of code in the "catch" area again:

captionInsPts.contents = "\r Description metadata not available";

using the other code instead (the "continue") resulted in the same error.


Okay I've had a look through the script you posted. Here's my thoughts.

 

1. Remove the massive try/catch in the Main function, so you can see actual errors if they arise. Try/catch should only be used in situations where you are more-or-less predicting errors that you are sure you don't care about. So clear line 39 and lines 193-196. (I say clear, rather than delete, because I'll be referring to line numbers later, so keep them.) Try/catch blocks should be short, and specific to a particular operation. And while you are developing your script, better to have none at all, so you can have your finger on the pulse, so to speak.

 

2. Change UndoModes.FAST_ENTIRE_SCRIPT to UndoModes.ENTIRE_SCRIPT. FAST_ENTIRE_SCRIPT can be flaky and doesn't provide full support of Undo. I mostly avoid using it. In this case the script was getting a weird reference error (the object no longer exists, that you mentioned) until I changed to ENTIRE_SCRIPT.

 

3. Lines 100-112 are causing problems. Perhaps you want something like this:

gb = container.geometricBounds;

container.geometricBounds = [
    gb[0],
    gb[1],
    gb[0] + maxHeight,
    gb[1] + maxWidth
];

But note that even though the UI says "mm" units, the script makes no attempt to enforce them. So `maxHeight` of "40mm" is actually 40pts.

 

Other than that, there are parts to the script that I don't understand at a quick glance, but these points are the main issues I noticed. Let me know where you get to after this.

- Mark

1 reply

m1b
Braniac
July 2, 2024

Hi @Bridgette.Is.Enthusiastic, normally you would do something like this:

 

var imgPath = img.itemLink;
var imgDescription = undefined;

try {
    imgDescription = imgPath.linkXmp.description;

    if (imgDescription)
        captionInsPts.contents = "\r" + imgDescription;
}
catch (err) {

    if (debug)
        $.writeln(err.message + ", line: " + err.line);

    captionInsPts.contents = "\r Description metadata not available";
}

 

 

So, if no error is thrown (and if the imgDescription has any content) it will set the contents they way you want.

I couldn't tell from your code whether this is actually going to solve your problem though. Let us know if it helped.

- Mark

 

P.S. You don't need the `finally` block unless you want to do something no matter if error occurred or not, and when your catch block returns control or throws an error deliberately. (This is more advanced so feel free to ignore.)

Bridgette.Is.Enthusiastic
Inspiring
July 2, 2024

thanks for your time!

 

I pulled everything I could out of the try...catch() because I kept running into issues with the variables inside of it. The code you provided resulted in the error "object is invalid" for this line:

captionInsPts.contents = "\r Description metadata not available";

even though "captionInsPts" works fine in the "try" part of the code. This was one of the many issues I ran into trying to set up error handling for this script - all something along the lines of "this part works fine outside of these catch brackets, but now that they're in here I have no idea what they are". 

Bridgette.Is.Enthusiastic
Inspiring
July 2, 2024

Hi @Bridgette.Is.Enthusiastic, okay please try this: After this line

captionInsPts = imgCaption.insertionPoints[-1];

add this:

if (!captionInsPts.isValid)
    alert('captionInsPts is not valid.');

My guess is that this alert will trigger. If I'm right, then you need to handle a case where the imgCaption has no insertionPoints. Something like this:

if (!captionInsPts.isValid)
    continue;

Maybe that will be enough for you to experiment? Or I've guessed wrong and the issue is something else!

- Mark


when I add that line of code in where you specified, I get an alert that says "Critical error: The requested action could not be completed because the object no longer exists., line: 142" which is referring this line of code in the "catch" area again:

captionInsPts.contents = "\r Description metadata not available";

using the other code instead (the "continue") resulted in the same error.