• MikeCamp
  • NEWBIE
  • 10 Points
  • Member since 2012

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 9
    Replies
We are co-developing some code with a external vendor.

We wrote some custom code that when certain field on the contact are updated, it creates a record in a sync object(SyncLog).
Then there is a trigger that calls a @future method to send that object to an external system. This is required for callouts in triggers.

This is working fine, however we have NPSP installed.

When the address changes it kicks off a address validation process in the @future context.  If the address gets validated, it updated the contact and the process creates the SyncLog (still in @future)
At this time we get an error - Future method cannot be called from a future or batch method.

So I figure this out and check for @future and call a method without @future.
Then we getan error
 - Http post failed with exception Callout from triggers are currently not supported.

Due to our agreement we are trying to avoid any third party integration utilities.

The callout need to happen in near realtime.

We are caught in a Catch 22.  Does anyone have any suggestions?



Here is a diagram of the problem:
User-added image
Here is the pertinent code.
trigger Code
 
if (!System.isFuture()) {
            SVC_SyncLogService.sendSyncLogFuture(new List<ID>(Trigger.newMap.keySet()));
        } else {
            SVC_SyncLogService.sendSyncLog(new List<ID>(Trigger.newMap.keySet()));
        }



SVC_SyncLogService Code

 
@future (callout=true)
    public static void sendSyncLogFuture(List<ID> SyncLogList) {
        try {
            sendSyncLog(SyncLogList);
        } catch (Exception e) {
            {exception code here}
        }
    }

   public static void sendSyncLog(List<ID> SyncLogList) {
        List<SyncLog__c> SyncLogRecordList = [{select goes here}];
        //if running as part of a test class do not call manager
        if(!Test.isRunningTest()){
            {vendorClass} Mgr = new {vendorClass}();
            Mgr.sendSyncLog(SyncLogRecordList);
        }
    }

 
I have a CanvasLifecycleHandler thst rewrites the url with a timeStamp.  Is it possible to assert in the test class that the url has been changed?  If so, how?

CanvasLifecycleHandler
public class CANV_LIFECYCLE_Registration
implements Canvas.CanvasLifecycleHandler {
    public Set<Canvas.ContextTypeEnum> excludeContextTypes(){
        Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>();
        return excluded;
    }
        
    public void onRender(Canvas.RenderContext renderContext) {
        Canvas.ApplicationContext app = renderContext.getApplicationContext();
        // get urlpath from canvas app
        string newURL = getURLPath(app.getCanvasUrl());

        //add random string to prevent caching
        newURL += '?R='+ DateTime.now().gettime();

        //update the url
        app.setCanvasUrlPath(newURL);
    }

    private string getURLPath(string canvasURL){
        String[] URLList = canvasUrl.split('/');
        string URLPath = '';
        for(Integer a = 3; a < URLList.size(); a++){
            URLPath += '/' + URLList[a];
        }
        return URLPath;
    }
}
What I have so far for Test Class (strait from docs here (https://developer.salesforce.com/docs/atlas.en-us.platform_connect.meta/platform_connect/canvas_testing_your_canvaslifecyclehandler.htm))
@isTest
private class CANV_LIFECYCLE_Registration_TEST {
    static testMethod void testDefaultMockValues(){
        // Test handler using the default mock RenderContext Canvas.Test creates
        CANV_LIFECYCLE_Registration handler = new CANV_LIFECYCLE_Registration();
        Canvas.Test.testCanvasLifecycle(handler,null);
    }
}

 
I randomly get this error in a trigger and the field(RPRegistrationID__c) on the custom object(RP_Registration__c) that I am querying is indexed(set as Unique and External ID)  Any sugestions on what is causing this?
Here is the code
if(!surveyUpdates.isEmpty()){
            Map<string,ID> regIDMap = new Map<string,ID>(); 
            for (RP_Registration__c thisReg : [SELECT Id, RPRegistrationID__c from RP_Registration__c
                where RPRegistrationID__c in :surveyUpdates]) {
                regIDMap.put(thisReg.RPRegistrationID__c,thisReg.ID);
            }

            //update survey to point registration
            for(Survey__c thisSurvey : surveys) {
                if(regIDMap.containsKey(thisSurvey.RPRegistrationID__c)){
                    thisSurvey.Registration__c = regIDMap.get(thisSurvey.RPRegistrationID__c);
                }
            }
Hi,
Does anyone know of a way to monitor or view a log of the OBM's from my production Org.
We have a WFR that sends a OBM to informatica and on to our mySQL.  Randomly the updates are not getting to mySQL and the informatica job does not seem to account for them either.  I am trying to figure out if SF is sending them.  I have another WFR that has same criteria that does a field update and it is firing.

Tried to get log from SF Support, but they are clueless and then when they finally understood what I was asking for they Sent me to Developer support.  They then closed the case because we can't afford Premier Support. 

I have a fix, but anyone have any ideas why this is happening?

Is my solution the best way to address error?

 

I have the following trigger giving me an "System.NullPointerException: Attempt to de-reference a null object" error intermittent error on  line 28 - newAttendee.Contact__c.addError('This contact is already registered for this event.');

 

Using test data in a sandbox the trigger works on some and throw exception on others.

 

Here is an overview of custom objects:

Event

- Registration

- Lookup from Registration to Event

- - Attendee

- - Master detail between Registration and Attendee

- - EventDetail__c is a formula  {eventID-contactID}

 

Here is the trigger

trigger TRG_Attendee_singleContactPerEvent on Attendee__c (before insert, before update) {
    // Make sure we are not adding a Attendee to the same Event     
        
    Map<String, Attendee__c> attendeeMap = new Map<String, Attendee__c>();
    for (Attendee__C Attendee : System.Trigger.new) {
        
        // Only check if adding to an active Registration.  
        if (Attendee.Registration__r.Status__c  != 'Canceled')
            {
            // Make sure another new Attendee in batch isn't also a duplicate  
            if (attendeeMap.containsKey(Attendee.EventContact__c)) {
                // If another new Attendee in batch is a duplicate set error  
                Attendee.Contact__c.addError('This contact is already registered for this event.');
            } else {
                // Add to list for check
                attendeeMap.put(Attendee.EventContact__c, Attendee);
            }
        }
    }
    

    // Using a single database query, find all the Attendees in  
    // the database that have the same EventContact as any  
    // of the Attendees being inserted or updated.  
    for (Attendee__C foundAttendee : [SELECT EventContact__c FROM Attendee__c
                      WHERE EventContact__c IN :attendeeMap.KeySet() and Registration_Status__c = 'Active']) {
            Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c);
            newAttendee.Contact__c.addError('This contact is already registered for this event.');
    }
}

 

I have fixed by putting if statement around line 27 and 28 like:

        if (attendeeMap.containsKey(foundAttendee.EventContact__c)){
            Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c);
            newAttendee.Contact__c.addError('This contact is already registered for this event.');
        }

 

We are co-developing some code with a external vendor.

We wrote some custom code that when certain field on the contact are updated, it creates a record in a sync object(SyncLog).
Then there is a trigger that calls a @future method to send that object to an external system. This is required for callouts in triggers.

This is working fine, however we have NPSP installed.

When the address changes it kicks off a address validation process in the @future context.  If the address gets validated, it updated the contact and the process creates the SyncLog (still in @future)
At this time we get an error - Future method cannot be called from a future or batch method.

So I figure this out and check for @future and call a method without @future.
Then we getan error
 - Http post failed with exception Callout from triggers are currently not supported.

Due to our agreement we are trying to avoid any third party integration utilities.

The callout need to happen in near realtime.

We are caught in a Catch 22.  Does anyone have any suggestions?



Here is a diagram of the problem:
User-added image
Here is the pertinent code.
trigger Code
 
if (!System.isFuture()) {
            SVC_SyncLogService.sendSyncLogFuture(new List<ID>(Trigger.newMap.keySet()));
        } else {
            SVC_SyncLogService.sendSyncLog(new List<ID>(Trigger.newMap.keySet()));
        }



SVC_SyncLogService Code

 
@future (callout=true)
    public static void sendSyncLogFuture(List<ID> SyncLogList) {
        try {
            sendSyncLog(SyncLogList);
        } catch (Exception e) {
            {exception code here}
        }
    }

   public static void sendSyncLog(List<ID> SyncLogList) {
        List<SyncLog__c> SyncLogRecordList = [{select goes here}];
        //if running as part of a test class do not call manager
        if(!Test.isRunningTest()){
            {vendorClass} Mgr = new {vendorClass}();
            Mgr.sendSyncLog(SyncLogRecordList);
        }
    }

 
I have a CanvasLifecycleHandler thst rewrites the url with a timeStamp.  Is it possible to assert in the test class that the url has been changed?  If so, how?

CanvasLifecycleHandler
public class CANV_LIFECYCLE_Registration
implements Canvas.CanvasLifecycleHandler {
    public Set<Canvas.ContextTypeEnum> excludeContextTypes(){
        Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>();
        return excluded;
    }
        
    public void onRender(Canvas.RenderContext renderContext) {
        Canvas.ApplicationContext app = renderContext.getApplicationContext();
        // get urlpath from canvas app
        string newURL = getURLPath(app.getCanvasUrl());

        //add random string to prevent caching
        newURL += '?R='+ DateTime.now().gettime();

        //update the url
        app.setCanvasUrlPath(newURL);
    }

    private string getURLPath(string canvasURL){
        String[] URLList = canvasUrl.split('/');
        string URLPath = '';
        for(Integer a = 3; a < URLList.size(); a++){
            URLPath += '/' + URLList[a];
        }
        return URLPath;
    }
}
What I have so far for Test Class (strait from docs here (https://developer.salesforce.com/docs/atlas.en-us.platform_connect.meta/platform_connect/canvas_testing_your_canvaslifecyclehandler.htm))
@isTest
private class CANV_LIFECYCLE_Registration_TEST {
    static testMethod void testDefaultMockValues(){
        // Test handler using the default mock RenderContext Canvas.Test creates
        CANV_LIFECYCLE_Registration handler = new CANV_LIFECYCLE_Registration();
        Canvas.Test.testCanvasLifecycle(handler,null);
    }
}

 
I randomly get this error in a trigger and the field(RPRegistrationID__c) on the custom object(RP_Registration__c) that I am querying is indexed(set as Unique and External ID)  Any sugestions on what is causing this?
Here is the code
if(!surveyUpdates.isEmpty()){
            Map<string,ID> regIDMap = new Map<string,ID>(); 
            for (RP_Registration__c thisReg : [SELECT Id, RPRegistrationID__c from RP_Registration__c
                where RPRegistrationID__c in :surveyUpdates]) {
                regIDMap.put(thisReg.RPRegistrationID__c,thisReg.ID);
            }

            //update survey to point registration
            for(Survey__c thisSurvey : surveys) {
                if(regIDMap.containsKey(thisSurvey.RPRegistrationID__c)){
                    thisSurvey.Registration__c = regIDMap.get(thisSurvey.RPRegistrationID__c);
                }
            }
Hi,
Does anyone know of a way to monitor or view a log of the OBM's from my production Org.
We have a WFR that sends a OBM to informatica and on to our mySQL.  Randomly the updates are not getting to mySQL and the informatica job does not seem to account for them either.  I am trying to figure out if SF is sending them.  I have another WFR that has same criteria that does a field update and it is firing.

Tried to get log from SF Support, but they are clueless and then when they finally understood what I was asking for they Sent me to Developer support.  They then closed the case because we can't afford Premier Support. 

I have a fix, but anyone have any ideas why this is happening?

Is my solution the best way to address error?

 

I have the following trigger giving me an "System.NullPointerException: Attempt to de-reference a null object" error intermittent error on  line 28 - newAttendee.Contact__c.addError('This contact is already registered for this event.');

 

Using test data in a sandbox the trigger works on some and throw exception on others.

 

Here is an overview of custom objects:

Event

- Registration

- Lookup from Registration to Event

- - Attendee

- - Master detail between Registration and Attendee

- - EventDetail__c is a formula  {eventID-contactID}

 

Here is the trigger

trigger TRG_Attendee_singleContactPerEvent on Attendee__c (before insert, before update) {
    // Make sure we are not adding a Attendee to the same Event     
        
    Map<String, Attendee__c> attendeeMap = new Map<String, Attendee__c>();
    for (Attendee__C Attendee : System.Trigger.new) {
        
        // Only check if adding to an active Registration.  
        if (Attendee.Registration__r.Status__c  != 'Canceled')
            {
            // Make sure another new Attendee in batch isn't also a duplicate  
            if (attendeeMap.containsKey(Attendee.EventContact__c)) {
                // If another new Attendee in batch is a duplicate set error  
                Attendee.Contact__c.addError('This contact is already registered for this event.');
            } else {
                // Add to list for check
                attendeeMap.put(Attendee.EventContact__c, Attendee);
            }
        }
    }
    

    // Using a single database query, find all the Attendees in  
    // the database that have the same EventContact as any  
    // of the Attendees being inserted or updated.  
    for (Attendee__C foundAttendee : [SELECT EventContact__c FROM Attendee__c
                      WHERE EventContact__c IN :attendeeMap.KeySet() and Registration_Status__c = 'Active']) {
            Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c);
            newAttendee.Contact__c.addError('This contact is already registered for this event.');
    }
}

 

I have fixed by putting if statement around line 27 and 28 like:

        if (attendeeMap.containsKey(foundAttendee.EventContact__c)){
            Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c);
            newAttendee.Contact__c.addError('This contact is already registered for this event.');
        }

 

In several projects, in several orgs, I've scheduled some Batch Apex jobs to run nightly to process large numbers of records. I've run into a couple of problems that are leaving me very uncertain about whether Batch Apex really can handle large jobs.

Every now and then, a job will fail with this error: Unable to write to any of the ACS stores in the alloted time. I first encountered this in September 2010. I filed a Case and created a discussion group posting (http://boards.developerforce.com/t5/Apex-Code-Development/Unable-to-write-to-any-of-the-ACS-stores-in-the-alloted-time/m-p/205908#M36022). After a few weeks, I was finally told that it was an internal issue that had been resolved. After months of running nightly Batch Apex jobs without this problem, it just recurred.

A second issue is that, every now and then, a Batch Apex job gets stuck in the queue in the "Queued" state. When you launch a Batch Apex job, it gets added to the queue in the "Queued" state, and when the system gets around to executing it, the job gets moved to a "Processing" state. Well, I have batch jobs that have been stuck in the "Queued" state since early January. I've had cases open on this problem for over a month, and while the Case finally found its way to Tier 3 Support, there's still no sign of a resolution.

In both cases, the issue is NOT an Apex coding problem. It's an issue with how the platform is queueing and processing Batch Apex jobs.

I'm wondeirng whether anybody else has run into these problems, or other problems executing Batch Apex jobs. What problems have you run into? How have you resolved or worked around them?

Thanks for your insights.

 
  • February 04, 2011
  • Like
  • 0