<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://ca-peterson.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ca-peterson.com/" rel="alternate" type="text/html" /><updated>2026-02-21T02:09:57+00:00</updated><id>https://ca-peterson.com/feed.xml</id><title type="html">Chris Peterson</title><subtitle>Miscellaneous ramblings usually related to Salesforce.com development.</subtitle><author><name>Chris Peterson</name></author><entry><title type="html">You Really Didn’t Mean to Use Week Year</title><link href="https://ca-peterson.com/2020/12/31/you-didnt-mean-to-use-week-year.html" rel="alternate" type="text/html" title="You Really Didn’t Mean to Use Week Year" /><published>2020-12-31T08:00:00+00:00</published><updated>2020-12-31T08:00:00+00:00</updated><id>https://ca-peterson.com/2020/12/31/you-didnt-mean-to-use-week-year</id><content type="html" xml:base="https://ca-peterson.com/2020/12/31/you-didnt-mean-to-use-week-year.html"><![CDATA[<p>It’s that time of year again: PTO, and holidays, and… DateTime formatting edge case bugs.</p>

<p>Every year I see an escalated customer case come in somewhere, that Apex is doing date/times wrong, since somehow the last week of December in 2020 shows up with a year of 2021!</p>

<p>Apex delegates to the very, very commonly used Java SimpleDateFormat for the format string provided to DateTime.format(), and if you <a href="https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">open the Java docs</a> you’ll see two values for year next to each other: “Y” for “Week Year” and “y” for year.</p>

<p>Almost nobody knows what “week year” actually means, but Tom Scott summarizes it well, a semi-obscure ISO format that guarantees 52 full weeks per year, even if they don’t align with the calendar year. So, turns out, you <strong>really</strong> want to be using “y”, not “Y”.</p>

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">If you're using YYYY instead of yyyy in your java/apex date formats: <a href="https://t.co/rC1ocHU1tQ">https://t.co/rC1ocHU1tQ</a></p>— Chris Peterson (@ca_peterson) <a href="https://twitter.com/ca_peterson/status/1344394112636649472?ref_src=twsrc%5Etfw">December 30, 2020</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<p>The net result of using “Y”? You display December 30th and 31st (depending on Locale) as being in the next year.</p>

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">every year 😠 <a href="https://t.co/2ADptN7WM3">pic.twitter.com/2ADptN7WM3</a></p>&mdash; new baby no sleep just vibes (@isEqualToDan) <a href="https://twitter.com/isEqualToDan/status/1341428193966891008?ref_src=twsrc%5Etfw">December 22, 2020</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>]]></content><author><name>Chris Peterson</name></author><summary type="html"><![CDATA[Your annual reminder that you really wanted 'yyyy' not 'YYYY' as your date format string.]]></summary></entry><entry><title type="html">SalesforceWay Podcast</title><link href="https://ca-peterson.com/event/2020/06/05/salesforceway-podcast.html" rel="alternate" type="text/html" title="SalesforceWay Podcast" /><published>2020-06-05T16:00:00+00:00</published><updated>2020-06-05T16:00:00+00:00</updated><id>https://ca-peterson.com/event/2020/06/05/salesforceway-podcast</id><content type="html" xml:base="https://ca-peterson.com/event/2020/06/05/salesforceway-podcast.html"><![CDATA[<p>Xi Xiao invited me on his podcast SalesforceWay, and we had a really interesting extended conversation about Apex, current and future. Give it a listen if you’re so inclined.</p>

<p>Have to say, he did an outstanding job on the editing.</p>

<ul>
  <li><a href="https://salesforceway.com/podcast/apex-language/">SalesforceWay All About Apex Part  1</a></li>
  <li><a href="https://salesforceway.com/podcast/apex-language2/">SalesforceWay All About Apex  2</a></li>
</ul>]]></content><author><name>Chris Peterson</name></author><category term="Event" /><category term="podcast" /><summary type="html"><![CDATA[Xi Xiao from the SalesforceWay podcast interviewed me about Apex in a long-form interview.]]></summary></entry><entry><title type="html">Salesforce Developers Podcast Episode</title><link href="https://ca-peterson.com/event/2020/02/17/salesforce-developers-podcast-episode.html" rel="alternate" type="text/html" title="Salesforce Developers Podcast Episode" /><published>2020-02-17T00:00:00+00:00</published><updated>2020-08-24T00:00:00+00:00</updated><id>https://ca-peterson.com/event/2020/02/17/salesforce-developers-podcast-episode</id><content type="html" xml:base="https://ca-peterson.com/event/2020/02/17/salesforce-developers-podcast-episode.html"><![CDATA[<p>Josh Birk spent quite a bit of time talking with me for the Salesforce Developers podcast. Our chat has a particular emphais on security and performance, but meanders all over.</p>

<p>He and his team did a phenomenal job editing it into something coherent (and enjoyable).</p>

<p>Go check it out: <a href="">https://developer.salesforce.com/blogs/2020/02/episode-17-spring-20-apex-with-chris-peterson.html</a></p>]]></content><author><name>Chris Peterson</name></author><category term="Event" /><category term="podcast" /><summary type="html"><![CDATA[Josh Birk interviews me about what it's like being Apex PM, hammer, and a couple fun stories]]></summary></entry><entry><title type="html">Talking about Apex Security on Spring ‘19 Release Readiness</title><link href="https://ca-peterson.com/event/2020/01/30/talking-about-apex-security-on-spring-19-release-readiness.html" rel="alternate" type="text/html" title="Talking about Apex Security on Spring ‘19 Release Readiness" /><published>2020-01-30T08:00:00+00:00</published><updated>2020-02-03T08:00:00+00:00</updated><id>https://ca-peterson.com/event/2020/01/30/talking-about-apex-security-on-spring-19-release-readiness</id><content type="html" xml:base="https://ca-peterson.com/event/2020/01/30/talking-about-apex-security-on-spring-19-release-readiness.html"><![CDATA[<p>The Salesforce Developer evangelism folks finally talked me into doing a live webinar for release readiness. Obviously I forgot to post this until after it happened - so now it’s a recorded webinar for all intents and purposes.</p>

<p>Still, some interesting things in here, not only in my sections about Apex, but the Communities improvements around MDAPI format are <em>massive</em>, and Flow offering system mode is a very interesting new development.</p>

<p>The ongoing improvements about the Invocable Method framework for exposing Apex actions into flow are impressive, and even if you’re traditionally an Apex-centric developer who may have avoided Flow, are something to be aware of since now Invocable actions don’t require many sacrifices, if any, in terms of the Apex API surface to support.</p>

<p><a href="https://www.salesforce.com/video/8176623/" title="https://www.salesforce.com/video/8176623/">https://www.salesforce.com/video/8176623/</a></p>

<p>Also, in case you prefer to read instead of watch the Developer Evangelist team did a great writeup on the Apex security features:</p>

<p><a href="https://developer.salesforce.com/blogs/2020/01/learn-moar-in-spring-20-with-field-level-security-in-apex.html" title="https://developer.salesforce.com/blogs/2020/01/learn-moar-in-spring-20-with-field-level-security-in-apex.html">https://developer.salesforce.com/blogs/2020/01/learn-moar-in-spring-20-with-field-level-security-in-apex.html</a></p>]]></content><author><name>Chris Peterson</name></author><category term="Event" /><category term="presentation" /><summary type="html"><![CDATA[I did a webinar, if you're interested in finalizers or Apex security you should check it out.]]></summary></entry><entry><title type="html">Apex Describe calls: What you need to know</title><link href="https://ca-peterson.com/apex/2020/01/21/apex-describe-calls-what-you-need-to-know.html" rel="alternate" type="text/html" title="Apex Describe calls: What you need to know" /><published>2020-01-21T21:00:00+00:00</published><updated>2020-01-22T21:45:00+00:00</updated><id>https://ca-peterson.com/apex/2020/01/21/apex-describe-calls-what-you-need-to-know</id><content type="html" xml:base="https://ca-peterson.com/apex/2020/01/21/apex-describe-calls-what-you-need-to-know.html"><![CDATA[<p>You may have noticed that as the schema of Salesforce has continued to expand that the Apex SObject describe API layer has also been getting more complex to use in performant and scalable ways. In this post I’m hoping to share some tips on best practices, as well as some of the more nuanced details about what we’ve been up to under the hood in terms of trying to improve the status quo. <a href="https://salesforce.stackexchange.com/a/219010/60">As always, the dev community was also up to the same thing</a>, and came up with some interesting tricks independently.</p>

<p>In Spring ‘20 the Apex team spent a substantial amount of effort to bring safe lazy loading of describe attributes into the language to attempt to minimize the up-front cost of building <code class="language-plaintext highlighter-rouge">Schema.SObjectDescribe</code> instances - especially if you don’t need to read every attribute of it for your use case. Internally, <code class="language-plaintext highlighter-rouge">Schema.DescribeSObjectResult</code> instances now keep a private copy of the context they were generated in - what namespace, API version, <code class="language-plaintext highlighter-rouge">with sharing</code>/<code class="language-plaintext highlighter-rouge">without sharing</code>, and a number of other aspects that can have an impact what’s accessible. For the sake of consistency with non-lazy <code class="language-plaintext highlighter-rouge">Schema.DescribeSObjectResult</code> instances, where all the attributes were calculated in a single security context, we have to actually restore the same context in which the describe was generated in, <em>then</em> calculate the attribute.</p>

<p>On that note though, we did discover that unless the “<em>Use Improved Schema Caching</em>” critical update is enabled that this could lead to functional changes in edge cases, especially when mixing and matching API versions in the same request. So to take advantage of this in Spring ‘20 requires at least one of two things to be true:</p>

<ol>
  <li>The “Use Improved Schema Caching” critical update is enabled in the org. <strong>This applies deferred mode as the default retroactively across all API versions.</strong></li>
  <li>The Apex code generating the describe is using the new overload, and passing in the DEFERRED <code class="language-plaintext highlighter-rouge">SObjectDescribeOptions</code> enum value to the <code class="language-plaintext highlighter-rouge">getDescribe()</code> call to specifically request lazy loading of properties on use.</li>
</ol>

<p>For ISV partners specifically, where it’s challenging (at best) to ask customers to enable a critical update across the board I’d strongly recommend making use of the new method overload for performance sensitive code paths to ensure your customers have minimal code overhead.</p>

<p>In other words, if you’re working on a managed package and want to ensure your customers are taking advantage of this deferred mode, you’d want your code to look something like</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DescribeSobjectResult dsr = Account.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED);
</code></pre></div></div>

<p>Deferred mode is especially useful when you aren’t going to need the <code class="language-plaintext highlighter-rouge">getChildRelationships()</code> data for a specific SObject type from the describe. As the schema of an organization grows in complexity pre-calculating this method was observed to be one of the most substantial increases in terms of CPU time as it in turns requires running a non-trivial volume of field-level <code class="language-plaintext highlighter-rouge">getDescribe()</code> calls to fully populate.</p>

<p>As a best-case example for DEFERRED:</p>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Actual results from a customer&#39;s org:<br /><br />Schema.describeSObjects(new String[]{&#39;User&#39;})[0].isAccessible();<br />---&gt; takes 700 ms<br /><br />User.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).isAccessible();<br />---&gt; takes 1 ms<br /><br />If only describeSObjects() supported DEFERRED...</p>&mdash; Zach McElrath (@zachelrath) <a href="https://twitter.com/zachelrath/status/1237111310233612288?ref_src=twsrc%5Etfw">March 9, 2020</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<p><br /></p>

<p>Take a look at the <a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_Schema_SObjectType.htm">Apex Developer Guide’s Spring ‘20 version’s topic on <code class="language-plaintext highlighter-rouge">Schema.SObjectType.getDescribe(options)</code></a>, which has a full truth table that describes the default behavior in more depth.</p>

<h2 id="when-to-not-be-lazy">When to Not be Lazy</h2>

<p>While being lazy, especially for describe objects, is amusingly a generally good quality there are situations where it may not be exactly what you want.</p>

<p>One particular case we discovered was Einstein related picklist fields. These have a fairly unique and complex implementation that automatically expands and contracts the valid scope of picklist entries based on what SObject types the current user context has access to. While lazy describe objects make every effort to restore the security context fully sometimes that’s not good enough to guarantee 100% accuracy for this type of field if the valid picklist values are interrogated in a different context. This is very much a case where you’d want to either ensure the same API version across all the code making use of the same describe instance, or else using the FULL describe mode to avoid any potential quirks.</p>

<p>To force the FULL mode, your code would end up looking like</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DescribeSobjectResult dsr = Account.SObjectType.getDescribe(SObjectDescribeOptions.FULL);
</code></pre></div></div>

<h2 id="consider-the-metadata-catalog">Consider the Metadata Catalog</h2>

<p>It is worth calling out that describes are not the only way to inspect the schema anymore, and in many cases may not be the optimal tool. If you haven’t ever made use of the metadata catalog family of standard objects they’re exceptionally well suited for getting specific bits of metadata about fields or objects without needing to search through the whole global describe for a match. For describe-like use cases, you’ll want to pay special attention to <a href="https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/tooling_api_objects_entitydefinition.htm"><code class="language-plaintext highlighter-rouge">EntityDefinition</code></a> and <a href="https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/tooling_api_objects_entityparticle.htm"><code class="language-plaintext highlighter-rouge">EntityParticle</code></a>`. Despite their docs being in the tooling API guide, the same SObjects and fields are available in the data API, which means you can query these in Apex without needing anything special like callouts.</p>

<p>For bonus fun, there’s aspects of entities exposed via the Metadata Catalog entities that aren’t in the Apex describe API, like ExternalSharingModel, which is the best way to detect what specific sharing model any standard or custom object is making use of.</p>

<p>In other words, a query like <code class="language-plaintext highlighter-rouge">SELECT NamespacePrefix, DeveloperName, ExternalSharingModel, InternalSharingModel FROM EntityDefinition</code> gives you back a wealth of info that isn’t even available via the describe API at all. And if you further refine it, say with a <code class="language-plaintext highlighter-rouge">WHERE NamespacePrefix = 'mine'</code> clause you can end up getting back details about the org schema much more efficiently than looping through Schema.getGlobalDescribe() results, calling getDescribe() on each, and then checking the namespace prefix. Any time you’re looking for a needle in the haystack of org schema you should be considering Metadata Catalog queries before describes.</p>

<p>Take a close look at the tooling API documentation, since there’s a number of hidden gems, like the Publisher field which can be used with the “isSalesforce” value to find standard vs custom objects, i.e.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sfdx force:data:soql:query -q "SELECT NamespacePrefix, QualifiedApiName, ExternalSharingModel, InternalSharingModel, Publisher.isSalesforce FROM EntityDefinition WHERE DeveloperName = 'Case'"                             

NAMESPACEPREFIX  QUALIFIEDAPINAME  EXTERNALSHARINGMODEL  INTERNALSHARINGMODEL  PUBLISHER.ISSALESFORCE
───────────────  ────────────────  ────────────────────  ────────────────────  ──────────────────────
null             Case              Private               ReadWriteTransfer     true
null             Case__c           Private               ReadWrite
Total number of records retrieved: 2.
</code></pre></div></div>

<p>Do note that in this example developerName is <strong>not</strong> the full API name of the SObject type, which is why we get back both the custom and standard “Case” objects when filtering on DeveloperName, and why we select the QualifiedApiName field, which does distingish between them via the __c suffix. Be sure to read the documentation about metadata catalog types carefully before you rely on specific behavior!</p>

<p>If you have any feedback, please let us know either on <a href="https://twitter.com/ca_peterson">twitter</a> or in the comments. I’m especially interested in feedback about the viability of the metadata catalog - let us know performance, functional, or any other kinds of concerns you have upon closer inspection.</p>]]></content><author><name>Chris Peterson</name></author><category term="Apex" /><category term="isv" /><category term="performance" /><summary type="html"><![CDATA[New options for working with Apex describe APIs in Spring '20. May be of special interest to ISVs.]]></summary></entry><entry><title type="html">On Internationalization</title><link href="https://ca-peterson.com/salesforce/2019/07/18/on-internationalization.html" rel="alternate" type="text/html" title="On Internationalization" /><published>2019-07-18T07:00:00+00:00</published><updated>2019-07-18T07:00:00+00:00</updated><id>https://ca-peterson.com/salesforce/2019/07/18/on-internationalization</id><content type="html" xml:base="https://ca-peterson.com/salesforce/2019/07/18/on-internationalization.html"><![CDATA[<h6 id="never-concatenate-labels">Never Concatenate Labels</h6>
<p>This really doesn’t end well with languages like Japanese, where sentence structure can be radically different. Instead, use replacement tokens and String.format (or equivalent).</p>

<p>In other words, labels like: <code class="language-plaintext highlighter-rouge">Hi, I'm a label for {0}</code> where you replace <code class="language-plaintext highlighter-rouge">{0}</code> with a different label as needed are good. While doing <code class="language-plaintext highlighter-rouge">Hi, I'm a label for '+'something'</code> is terrible and will cause horrible pain.</p>

<p>If you apply formatting or hyperlinks to a subsection of your label this task becomes a lot harder than it sounds.</p>

<ul>
  <li>In <strong>lightning</strong>: make use of <a href="https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_ui_outputRichText.htm">ui:outputRichText</a>. This will allow formatting HTML, to the same standards as rich text fields in the native UI, but strip all sorts of permutations of exploits or scripting out. Links work too. <strong>Do not use <a href="https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_aura_unescapedHtml.htm">aura:unescapedHTML</a> for this!</strong></li>
</ul>

<p>In my case where I did need formatting and token replacement I ended up having to define a helper for my component that builds the ready to use strings, and adding 
 <code class="language-plaintext highlighter-rouge">&lt;aura:attribute type="Object" name="complexLabels" /&gt;</code>. Without this, you’ll get warnings (and later on errors) about access checks, since you can’t dynamically create new view properties in lightning, but you can add new keys to an Object. In the helper, process and build the labels, then do something like <code class="language-plaintext highlighter-rouge">cmp.set('v.complexLabels', {});</code> and <code class="language-plaintext highlighter-rouge">cmp.get('v.complexLabels').exampleLabel = 'blah';</code></p>

<p>While outputRichText takes care of filtering out things like XSS attempts, you still make way to do HTML escaping on the $Label values to prevent people from doing silly things like adding image tags in label translations.</p>

<ul>
  <li>In <strong>visualforce</strong>: you can prepare labels in the view pretty simply: make use of apex:outputText’s ability to accept apex:param values in a <code class="language-plaintext highlighter-rouge">String.format</code>-like way, as well as <code class="language-plaintext highlighter-rouge">HTMLENCODE</code> in merge expressions.</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;apex:outputText escape="false" value="{!HTMLENCODE($Label.labelWithReplacementTokens)}"&gt;
	&lt;apex:param value="&lt;b&gt;{!HTMLENCODE($Label.toReplaceWith)}&lt;/b&gt;" /&gt;
&lt;/apex:outputText&gt;
</code></pre></div></div>

<p>or, in terms more practical for a demo:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;apex:page showHeader="false"&gt;
    &lt;apex:outputText escape="false" value="{!HTMLENCODE('&lt;i&gt;this text will not be italicized. but this will be bolded: {0}&lt;/i&gt;')}"&gt;
		&lt;apex:param value="&lt;b&gt;{!HTMLENCODE('see?')}&lt;/b&gt;" /&gt;
	&lt;/apex:outputText&gt;
&lt;/apex:page&gt;
</code></pre></div></div>

<p>which nets you:</p>

<blockquote>
  <p>&lt;i&gt;this text will not be italicized. but this will be bolded: <strong>see?</strong>&lt;/i&gt;</p>
</blockquote>

<h6 id="dont-forget-custom-objects">Don’t Forget Custom Objects</h6>
<p>The translation workbench doesn’t include custom objects labels, or their <code class="language-plaintext highlighter-rouge">Name</code> field. To get these you can</p>

<ul>
  <li>Create a tab for your custom object, then use the setup UI:  <em>Setup &gt; Customize &gt; Tab Names And Labels &gt; Rename Tabs and Labels</em></li>
  <li>Use the metadata API (no tabs required).</li>
</ul>

<p>Considering you’re likely putting this all into source control anyways it seems like the metadata API is the way to go. These translations are stored alongside custom field translations (the kind you use the translation workbench for) in the <a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_customobjecttranslation.htm"><code class="language-plaintext highlighter-rouge">CustomObjectTranslation</code></a> metadata type. The various permutations (masculine/feminine, singular/plural, and all other sorts of language specific variants) go into the <a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_customobjecttranslation.htm"><code class="language-plaintext highlighter-rouge">caseValues</code></a> element.</p>

<p>Read the docs for the full details, but as something to get you started, you’re likely going to need to add/edit something like this in your object translation metadata files:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;nameFieldLabel&gt;Name Field Label&lt;/nameFieldLabel&gt; 
&lt;caseValues&gt;
     &lt;plural&gt;false&lt;/plural&gt;
     &lt;value&gt;My Object Label&lt;/value&gt;
&lt;/caseValues&gt;
&lt;caseValues&gt;
     &lt;plural&gt;false&lt;/plural&gt;
     &lt;value&gt;My Object Labels&lt;/value&gt;
&lt;/caseValues&gt;
</code></pre></div></div>

<h6 id="lightning-doesnt-include-labels-in-packages">Lightning Doesn’t Include Labels in Packages</h6>
<p>This is a known, <a href="https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/labels_value_provider_platform.htm">and documented</a>, limitation today:</p>

<blockquote>
  <p>Custom labels referenced in a Lightning component are not automatically added when you create a package containing the Lightning component. To include a custom label in a package, another member of the package, such as a Visualforce page, must reference the custom label.</p>
</blockquote>

<p>Still, it blindsides anybody who doesn’t RTFM sufficiently (like me a couple months ago). To get these labels into your package you need to reference them in visualforce or apex. Creating an <code class="language-plaintext highlighter-rouge">@isTest</code> apex class for this with no test methods is great, since you don’t have to get test coverage for your labels then. Just make sure you add it to your package, since as a test class nothing will depend on it.</p>

<h6 id="think-about-de-protecting-your-labels">Think About De-Protecting Your Labels</h6>

<p>If you’re delivering your app as a managed package that you expect your end users to customize, think about removing the protected checkbox on your labels. The cons of this are that you can’t delete labels later, but the upside is that customers can reference your packaged labels in their customization. This will save them the pain (and expense) of having to have two sets of labels for the same text.</p>

<p>In a non-translation related note, this also makes declarative customization much easier. Protected labels have a cascading nature, so if you use one in a formula field your customers won’t be able to make their own formula fields referencing yours!</p>

<p>If you’re worried about running out of label space, be aware it is a soft limit, although you shouldn’t go crazy just because of that!</p>]]></content><author><name>Chris Peterson</name></author><category term="Salesforce" /><category term="visualforce" /><category term="i18n" /><summary type="html"><![CDATA[Practical introductory best practices for internationalization support on Salesforce with aura components or Visualforce.]]></summary></entry><entry><title type="html">Leaky Abstractions: Apex Exception Types</title><link href="https://ca-peterson.com/2015/01/22/leaky_abstractions_apex_exception_types.html" rel="alternate" type="text/html" title="Leaky Abstractions: Apex Exception Types" /><published>2015-01-22T08:00:00+00:00</published><updated>2015-01-22T08:00:00+00:00</updated><id>https://ca-peterson.com/2015/01/22/leaky_abstractions_apex_exception_types</id><content type="html" xml:base="https://ca-peterson.com/2015/01/22/leaky_abstractions_apex_exception_types.html"><![CDATA[<p>Apex like java it’s built upon has exceptions as the core way of dealing with, er, exceptional situations. Apex exceptions have always had a couple oddities that I started poking deeper into.<br /><br />The first sign Exception types are different than any other apex class is that their naming convention is enforced by the compiler itself. You’ll get a compilation failure if you try something like<br /><br /><script src="https://gist.github.com/capeterson/9e88b1f710fdb88dd44f.js?file=name.cls"></script><br /><br />But the rabbit hole goes much deeper. Try and do something totally <b>crazy</b> like define a no-args constructor for our exception type:<br /><br /><script src="https://gist.github.com/capeterson/9e88b1f710fdb88dd44f.js?file=noargs.cls"></script><br /><br />That’s… odd. Defining a no-args constructors <em>anywhere</em> else in apex is perfectly valid, and in the case of global classes very wise (since if you define another constructor the implicit global one goes away. That was a fun week of compile failures). Let’s try doing something else, like defining a constructor that takes a message argument:<br /><br /><script src="https://gist.github.com/capeterson/9e88b1f710fdb88dd44f.js?file=stringarg.cls"></script><br /><br />Same thing again. Odd. Well we can always do something hacky like define another constructor with a boolean arg that is just ignored. Works well enough, although it’s a bit of an eyebrow-raiser in code review. Maybe there’s one last thing we can try though, how about overriding setMessage to do our boilerplate concatenation.<br /><br /><script src="https://gist.github.com/capeterson/9e88b1f710fdb88dd44f.js?file=nooverride.cls"></script><br /><br />Oh, how silly, I forgot the override keyword since we’re overriding a superclass’s method! When we add that things should all work out!<br /><br /><script src="https://gist.github.com/capeterson/9e88b1f710fdb88dd44f.js?file=nosuper.cls"></script><br /><br />Oh. Wait, but what? You only get the message about needing override if you’re overriding a superclass method, but simultaneously the compiler denies there being a superclass?<br /><br />I don’t have any way of telling for sure, but I have to hypothesize that this is done as a security measure. Exceptions would seem like a great target to use if you wanted to break out of the apex runtime’s sandbox (they’re mentioned it compiles apex to java bytecode now, which would imply it’s executed via reflection), so they appear to have taken a sensible approach of not exposing anything about java exception types within apex.<br /><br />One last thing to really break your brain. If we define a virtual exception type and extend that we <b>can</b> override setMessage, it just doesn’t get invoked by the template-injected constructors we just tried, and failed, to make.<br /><br /><script src="https://gist.github.com/capeterson/9e88b1f710fdb88dd44f.js?file=wat.cls"></script><br /><br />What extending exception in apex seems to do then is not subclass anything like you’d expect, but instead apply a pre-built template. What else it does besides constructors I have no idea, but it just goes to prove the <a href="http://en.wikipedia.org/wiki/Leaky_abstraction">old adages about non-trivial abstractions</a> true. I really can’t complain either, the apex team had to figure out some pretty tough engineering problems and if this is the worst (non-intentional) oddity in the class system I’ll take it.</p>]]></content><author><name>Chris Peterson</name></author></entry><entry><title type="html">Presenting at Dreamforce ‘14 tomorrow - “Faster SOQL, Yes Please”</title><link href="https://ca-peterson.com/salesforce/2014/10/15/presenting_at_dreamforce_14_tomorrow_faster_soql_yes_please.html" rel="alternate" type="text/html" title="Presenting at Dreamforce ‘14 tomorrow - “Faster SOQL, Yes Please”" /><published>2014-10-15T07:00:00+00:00</published><updated>2014-10-15T07:00:00+00:00</updated><id>https://ca-peterson.com/salesforce/2014/10/15/presenting_at_dreamforce_14_tomorrow_faster_soql_yes_please</id><content type="html" xml:base="https://ca-peterson.com/salesforce/2014/10/15/presenting_at_dreamforce_14_tomorrow_faster_soql_yes_please.html"><![CDATA[<p>If the room isn’t already over capacity come drop on by my session! Moscone West 2009 @ 11:30am.<br /><br />If you can’t know that it’s based in large part upon a blog me and my co-presenter did: <a href="https://developer.salesforce.com/page/Developing_Selective_Force.com_Queries_through_the_Query_Resource_Feedback_Parameter_Pilot">Developing Selective Force.com Queries through the Query Resource Feedback Parameter</a></p>

<p><br />I’m told it will be recorded, and it might be possible to convince me to do another run of it at the <a href="http://www.meetup.com/ForceDotCom/">San Francisco Developer User Group</a> if anybody wants.</p>

<p>[Update] It was recorded!</p>

<ul>
  <li><a href="https://speakerdeck.com/ca_peterson/df14-faster-soql-yes-please">Slides</a></li>
  <li><a href="http://dreamforce.vidyard.com/watch/4MfH1Hne0EV76ChTjSWfbQ">Video</a></li>
</ul>]]></content><author><name>Chris Peterson</name></author><category term="Salesforce" /><category term="event" /></entry><entry><title type="html">Best Practice: When to Use Public Test Classes</title><link href="https://ca-peterson.com/apex/2014/08/03/best_practice_when_to_use_public_test_classes.html" rel="alternate" type="text/html" title="Best Practice: When to Use Public Test Classes" /><published>2014-08-03T07:00:00+00:00</published><updated>2014-08-03T07:00:00+00:00</updated><id>https://ca-peterson.com/apex/2014/08/03/best_practice_when_to_use_public_test_classes</id><content type="html" xml:base="https://ca-peterson.com/apex/2014/08/03/best_practice_when_to_use_public_test_classes.html"><![CDATA[<p>Since the <a href="https://developer.salesforce.com/releases/release/Winter12/Public+Test+Classes+in+Apex">APIv23.0 release (aka Winter 12)</a> it’s been possible to have a non-private class annotated @isTest. You might first wonder why this would ever be useful.<br /><br />If you aren’t using <a href="https://github.com/financialforcedev/fflib-apex-mocks">some sort of mocking framework</a>, or even if you are, there’s a quite good chance that you’ll have common logic in your test methods. Chances are this logic is for things like mundane data setup that’s never going to be used outside of a test context. The big win from this feature is that you can make non-test public methods inside @isTest classes.<br /><br />My favorite feature of doing so is compile-time validation that your method is only being used inside tests; referencing a isTest class’ public methods from a non-test context fails to execute them by throwing a (catchable) TypeException. Beyond that any methods defined this way don’t count as code that needs it’s own test coverage, so you don’t have to have a (hypothetically named) TestUtilsTest class to go with your TestUtils.<br /><br />Even more interesting to the ISVs among us is that <a href="http://salesforce.stackexchange.com/a/42310/60">isTest classes their contained methods can be global</a>. This means that as a package author you can potentially expose test-only methods to do things that would otherwise be forbidden, like disabling triggers or creating a predefined set of baseline data that customers might not be able to initialize.<br /><br />In the grand scheme of things it’s hardly more than a neat little trick, but these neat little tricks add up over time and end up making all the difference in the world.</p>]]></content><author><name>Chris Peterson</name></author><category term="Apex" /><category term="isv" /></entry><entry><title type="html">Worst Practice: editing JSON with regex</title><link href="https://ca-peterson.com/salesforce/2014/03/23/worst_practice_editing_json_with_regex.html" rel="alternate" type="text/html" title="Worst Practice: editing JSON with regex" /><published>2014-03-23T07:00:00+00:00</published><updated>2014-03-23T07:00:00+00:00</updated><id>https://ca-peterson.com/salesforce/2014/03/23/worst_practice_editing_json_with_regex</id><content type="html" xml:base="https://ca-peterson.com/salesforce/2014/03/23/worst_practice_editing_json_with_regex.html"><![CDATA[<p>One of the fundamental tenets of building a large managed app is that all of your developers should of course work outside of the packaging org until it’s time to actually release. Normally the features built into apex around implicitly preferring your app’s namespace handle this for you: [SELECT field__c FORM Obj__c] works with or without being in the namespaced org (the only place the namespace prefix applies).<br /><br />However when you start building rich client applications this gets much more complex, as the JSON serializer <b>always</b> includes the namespace prefix. If you build a client app to expect field__c and it finds ns__field__c in the response you’re going to have an especially bad day when it comes to post-packaging testing.<br /><br />You can try and serialize the JSON yourself, removing the namespace prefix from any keys as needed, but this requires some dramatic shifts in how your apex works, and precludes using many of the built-in features of JSON.serialize.<br /><br />Enter regex. While not documented explicitly it’s been said before that String.replaceAll invokes the underlying java implementation, which happens to not only support regex, but regex <b>with capture groups</b>.<br /><br />With a bit of care you can build a regex that will only match JSON keys, and further only keys that start with your namespace prefix (so as to allow other managed fields to be included without clobbering yours), something like <code class="language-plaintext highlighter-rouge">([a-zA-Z0-9_-]+":)</code> - worth noting this won’t match all valid JSON due to the lack of handling whitespace before the colon. However the apex JSON.serialize method’s results will consistently match with this.<br /><br />Combining the two tricks leads us to some code along the lines of:<br /><script src="https://gist.github.com/capeterson/9731104.js"></script><br /><br /><br />Whatever Object (<span style="font-family: Courier New, Courier, monospace;">subject</span> in the sample code), or collections of Object are serialized will automatically have any and all namespace prefixes removed by that regex. A neat trick, especially when like me you discover this particular hurdle late in the development cycle.</p>]]></content><author><name>Chris Peterson</name></author><category term="Salesforce" /></entry></feed>