1

In my visualforce page, I have defined an Apex method from my controller to execute with the "action" attribute of the page.

This is the method:

    public void verificarAdjuntos(){
    Boolean empresaUY = cv != null ? cv.ERPvs__Empresa_1__r.ERPvs__Empresa_UY__c : cpv.ERPvs__Empresa__r.ERPvs__Empresa_UY__c;

    if(!empresaUY){
        verificarQR();
    }else{
        verificarPDFCFE();
    }
}

From those two methods that could be called, the one that throws the error is the first one:

    public static String getImageServer(ERPvs__Comprobante_Punto_de_Venta__c cpv){

    ApexLogger.debug(LoggingLevel.WARN, '>> >> getImageServer(ERPvs__Comprobante_Punto_de_Venta__c cpv)'); 

    String result;

    if(cpv.CAE__c != null && cpv.Fecha_vencimiento_CAE__c!= null){
        ERPvs__Facturacion_Electronica__c configuracion = ERPvs__Facturacion_Electronica__c.getInstance();

        String url = configuracion.ERPvs__URL_AFIP_QR__c;

        url += '?p=';

        url += EncodingUtil.base64Encode(Blob.valueOf(createJson(cpv)));

        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        
        req.setEndpoint( configuracion.ERPvs__URL_QR__c + '?size=125x125&data='  + EncodingUtil.urlEncode(url, 'UTF-8'));
        req.setMethod('GET');
        
        try {
            ApexLogger.debug(LoggingLevel.WARN, 'Llamada REST'); 
            if(! Test.IsRunningTest() ){
                res = http.send(req);
                ApexLogger.debug(LoggingLevel.WARN, 'Response: ' + res); 
            }
        } catch(System.CalloutException e) {
            ApexLogger.debug(LoggingLevel.WARN, 'Callout error: '+ e); 
            ApexLogger.debug(LoggingLevel.WARN, res.toString()); 
        }   
        
        ApexLogger.debug(LoggingLevel.WARN, 'res: '+ res); 

        
        if (res != null && res.getStatusCode() == 200){

            ApexLogger.debug(LoggingLevel.WARN, res.getHeader('Content-Type')); 

            ApexLogger.debug(LoggingLevel.WARN, 'body: ' + res.getBodyAsBlob()); 
            Attachment qr = new Attachment(ParentId = cpv.Id, Name= 'AFIP QR.png', body = res.getBodyAsBlob());    
            insert qr; 
        } 

    }
    
    ApexLogger.debug(LoggingLevel.WARN, 'result: ' + result); 

    return result;
    
}

As you can see, an insert is being made if the result of a callout is successful. When verifying the log, the code gets to the start of the insert and then throws the error. The problem with this is that I searched for the causes of that error, but I'm not calling this method in the constructor or getters of the Controller, it is in within the action attribute, so why is it failing?

Nothing about how the code is made indicates that the DML could be executing in a read-only context, unless I'm missing something. Any help would be appreciated!

1 Answer 1

2

It's failing because Salesforce says that you cannot perform DML in a controller method used in the action attribute of an <apex:page>.

From the relevant documentation

The action method invoked when this page is requested by the server. Use expression language to reference an action method. For example, action="{!doAction}" references the doAction() method in the controller. If an action isn’t specified, the page loads as usual. If the action method returns null, the page simply refreshes.

This method is called before the page is rendered, and allows you to optionally redirect the user to another page.

Important: Do not use this action for initialization or DML.

1
  • OH! How could I miss that. I've been searching for almost an HOUR, and I actually found some answers on some posts that indicated otherwise, that is why I was so confused. Thanks a lot! Commented Feb 16, 2023 at 15:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .