Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- Be respectful, on topic and if you see a problem, Flag it.
If you would like to contact our Community Manager personally, feel free to send a private message or an email.
Preserve ID through a try/catch?
EvanReese
Member, Mentor Posts: 2,135 ✭✭✭✭✭
I have a feature that I know will fail in certain scenarios, and I'd like to use a try/catch statement to first try my ideal one, and, if it fails, change some settings and try again. Here's what I've tested:
var mainBody; try silent { extrude(context, id + "mainBody", mainDef); mainBody = qCreatedBy(id + "mainBody", EntityType.BODY); } catch (error) { mainDef.hasDraft = false; mainDef.hasSecondDirectionDraft = false; extrude(context, id + "mainBody", mainDef); mainBody = qCreatedBy(id + "mainBody", EntityType.BODY); }This isn't working for me. If I change the id of the function in the catch statement as follows, it works
extrude(context, id + "mainBodyWithoutDraft", mainDef); mainBody = qCreatedBy(id + "mainBodyWithoutDraft", EntityType.BODY);The issue is that anything downstream related to this fails, because the id of the resulting body is different. How can I make featurescript treat the bodies from either function as the same thing? is opNameEntity() helpful here?
Evan Reese
0
Best Answers
-
NeilCooke Moderator, Onshape Employees Posts: 5,681Here's a simple example I coded just to check my syntax:
const extrudeId = id + "extrude"; for (var i in [0, 1]) // max 2 loops - change these numbers to make extrude fail/succeed in this test { startFeature(context, extrudeId); try silent { opExtrude(context, extrudeId + "body", { "entities" : definition.myQuery, "direction" : evOwnerSketchPlane(context, { "entity" : definition.myQuery }).normal, "endBound" : BoundingType.BLIND, "endDepth" : i * inch }); endFeature(context, extrudeId); // execution gets this far so feature completed break; } catch { abortFeature(context, extrudeId); // execution fails so do not commit/keep id } } opFillet(context, id + "fillet", { "entities" : qCreatedBy(extrudeId, EntityType.EDGE), "radius" : 0.1 * inch });
Senior Director, Technical Services, EMEAI0 -
lana Onshape Employees Posts: 706@Evan_Reese
try using id + unstableComponent("extrudeWDraft" ) and id + unstableComponent("extrudeNoDraft") . unstableComponent will prepend * to the input string, that would make results of two features interchangeable for downstream references.
1
Answers
I case I'm actually asking the wrong thing altogether, I'm solving for cases where extruding with draft will fail because there won't be any faces to draft. In those cases I'd like to just switch to extruding without draft without the user having to know that's happening, and without wrecking any downstream relationships. One workaround I'd like to avoid is copying the entire extrude feature code base and making the draft part a "try" statement instead of failing the feature. I might be okay with just always extruding without draft and manually adding the draft code to my feature, but intuition says there's a much better way to solve that, and I'd like to know what it is.
I looked at your example of the startFeature() and abortFeature() functions, but I still don't understand how to use them. Here's what I tried, which I'm sure will look silly once I know what they actually do, but there's not documentation on them because they're marked @internal.
Thanks! It still doesn't solve the issue I'm trying to solve, which is that the "try extrude" body is different than the "catch extrude" body, which will make downstream things fail. A hack I can think of which I think would solve my issue might be:
- Do a dummy "test extrude" to check whether it will fail
- Use that work/fail to set a boolean
- Based on the bool, turn draft off for the "real extrude"
- delete the "test extrude body"
That just feels like a big kludge, which is usually a clue to me that I'm doing it "wrong" and I have something I can learn. I also don't want to add that extra overhead if I don't need to. Any other ideas?for a very simple feature, here i create 2 sketches, if sketch 1 query is defined (selected) then it creates an extrude. if sketch 1 is undefined (unselected. if you break the sketch instead this will break the query for the sketch) then it goes to sketch2. with this you can boolean another part and unselect/reselect the sketch 1 and have the boolean work.
thanks! This looks like a variation of the Assign Identity feature code. This is definitely a handy thing to know for another scenario. I tried something like this, but as you say, I'd need to assign the ID for every entity (body, edge, vertex), which in my case, could be thousands. I ended up going with the startFeature() method, which is exactly what I was looking for.
Actually that wasn't the ticket after all, but it feels like the right solution if it can be made to work. Here's an example document of exactly the case I'm trying to solve for. The reason draft makes it fail is that there are no side faces to draft. With the native extrude, this doesn't matter, because you just un-check draft, but for my thing I want to do downstream things to that part either way, which might also have draft.
Here's the code I'm working with based on what you sent.
try using id + unstableComponent("extrudeWDraft" ) and id + unstableComponent("extrudeNoDraft") . unstableComponent will prepend * to the input string, that would make results of two features interchangeable for downstream references.
That solved it! Quite simply I should add. Thanks so much for taking the time.
I can't say I understand what's going on here though. I'm looking at the context.fs feature studio and see that unstableComponent() just prepends ANY_ID to a string and that ANY_ID is declared as "*", and that treats it as a wildcard, which a google search tells me it's kind of like "." in regex, but that's about where I fizzle out. Is there somewhere good for me to read up on it?