+ Start a Discussion
Scott M - SFDC FanScott M - SFDC Fan 

Argument 1 cannot be null

Hi everyone,

 

I hate just throwing up code and saying "what's wrong with it?" but I am not an experienced programmer and I just can't find the issue. So I am hoping someone more experienced will find what is wrong. I am getting the "Argument 1 cannot be null" error from the following code. It is supposed to be an image viewer for images saved as case attachments (something I wish SF had standard BTW).

 

The funny thing is, the code below works on another object with a different page....so, go figure...

 

Here is the controller class

 

public class ImageViewController
{
    private final SObject so;
    private List<Photo> myPhotos = new List<Photo> ();
    
    
    public ImageViewController (ApexPages.StandardController controller)
    {
        this.so = controller.getRecord ();
        fetchPhotos ();
    }

    public class Photo
    {
        String id;
        String url;
        String name;
        
        public Photo (String ipId, String ipName)
        {
            id   = ipId;
            url  = '/servlet/servlet.FileDownload?file=' + id;  // This is the standard SFDC manner to "download" attachments.
            name = ipName;
        }
        
        public String getId ()
        {
            return id;
        }
        
        public String getUrl ()
        {
            return url;
        }
        
        public String getName ()
        {
            return name;
        }
        
    }

    private void fetchPhotos ()
    {
        myPhotos.clear ();  // Empty list
        
        for (Attachment a : [Select Id, Name, ContentType From Attachment Where ParentId = :so.Id])
        {   
            if (!a.Name.endsWith ('tif')) // Don't let TIFs get compared, as these can't be viewed by the viewer.
            {  
                if (a != null && (a.ContentType != '' || a.Id != '' || a.Name != '')) // If no data in the field, skip. 
                {
                    try
                    {
                        if (a.ContentType.contains ('image/'))  // Only add images except TIFs to the list, ignore all other types
                        {
                            myPhotos.add (new Photo (a.Id, a.Name));
                        }
                    } 
                    catch (Exception e)
                    {
                        ApexPages.addMessages(e);
                        Exception e1;
                        ApexPages.addMessages(e1);
                    }
                }
            }
        }
            
    }
                               
    public List<Photo> getPhotos ()
    {
        return myPhotos;
    }         
        
}

 

And this is the page

 

<apex:page standardController="Case" extensions="ImageViewController" showHeader="false" sidebar="false" standardStylesheets="false">
    
    <apex:styleSheet value="{!URLFOR($Resource.picbox,'picbox.css')}"/> 
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"/> 
    <apex:includeScript value="{!URLFOR($Resource.picbox,'picbox.js')}"/>
    
    
          <script>
               if (!/android|iphone|ipod|series60|symbian|windows ce|blackberry/i.test(navigator.userAgent)) {
                    jQuery(function($) {
                        $("a[rel^='lightbox']").picbox({/* Put custom options here */}, null, function(el) {
                        return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
                        });
                    });
               }
               
         </script>        
  
           <apex:messages />

          <apex:repeat value="{!Photos}" var="p">
                <a rel="lightbox-viewer" href="{!p.url}"  title="{!p.name}" id="{!p.name}">
                     <img width="150" height="150" alt="{!p.name}" src="{!p.url}" title="{!p.name}" />
                </a>
              
           </apex:repeat>

      
</apex:page>
                

 Any help will be appreciated.

 

Regards,

 

Scott

crop1645crop1645

The debug log will tell you on what line# the error is occurring. 

 

The error message means that you are using a method call whose first argument must be non-null.

 

Your second call to addError is the issue -- e1 is null as you have coded it

Scott M - SFDC FanScott M - SFDC Fan

Thanks for your answer. But to be honest, I am not sure what you mean. Second call to addError? Do you mean addMessages in the catch?

 

And what get's me, this all works great in our Sandbox....

 

Scott

crop1645crop1645

sorry for the late response

 

the second addmessages(e1) will fail because e1 is null; you need a constructor invocation to instantiate it:

 

MyException e1 = new MyException('some string'); and you'll need to define a:

 

public class MyException extends Exception {}

 as you can't do Exception e1 = new Exception('some string');

 

try
                    {
                        if (a.ContentType.contains ('image/'))  // Only add images except TIFs to the list, ignore all other types
                        {
                            myPhotos.add (new Photo (a.Id, a.Name));
                        }
                    } 
                    catch (Exception e)
                    {
                        ApexPages.addMessages(e);
                        Exception e1;
                        ApexPages.addMessages(e1);
                    }
Scott M - SFDC FanScott M - SFDC Fan

Thanks Eric.

Scott M - SFDC FanScott M - SFDC Fan

Ok. I just deleted the e1 exception code and now the viewer is working, but I am getting this shown in the viewer.

 

Attempt to de-reference a null object

 

Have no idea why this is now happening, as this isn't happening in the sandbox. (how can that happen too?). I must also say, I did all this programming several months ago and everything I learned at the time I've forgotten....sorry for my ignorance....and thanks for any help.

 

Scott

crop1645crop1645

scamo:

 

1 - Go to Setup | Monitoring | Debug Logs and turn on debug logging for your user id

2 - Repeat the test

3 - INspect the debug log. You will see the statement number where the error occurs

 

Alternatively, in your catch block, use 

 

addmessages(e.getMessage() + ' line#:' + e.getLineNumber());

 

I suspect the error is that a.contentType is NULL -- you are testing for null string, but not null in the prior statement

 

Also, there is no need to test a != null as the for loop will only return Attachments if they exist

Scott M - SFDC FanScott M - SFDC Fan

Hi,

 

Sorry, opening this old thread back up, as my boss wants this to work with cases now.

 

The strange thing is, this code works in our Sandbox with Case records. It works in our production org with records from a custom object. But, it doesn't work with the Case records in our production org. Strange...

 

This is the controller code.

 

public class ImageViewController
{
    private final SObject so;
    private List<Photo> myPhotos = new List<Photo> ();
    
    
    public ImageViewController (ApexPages.StandardController controller)
    {
        this.so = controller.getRecord ();
        fetchPhotos ();
    }

    public class Photo
    {
        String id;
        String url;
        String name;
        
        public Photo (String ipId, String ipName)
        {
            id   = ipId;
            url  = '/servlet/servlet.FileDownload?file=' + id;  // This is the standard SFDC manner to "download" attachments.
            name = ipName;
        }
        
        public String getId ()
        {
            return id;
        }
        
        public String getUrl ()
        {
            return url;
        }
        
        public String getName ()
        {
            return name;
        }
        
    }

    private void fetchPhotos ()
    {
        myPhotos.clear ();  // Empty list
        
        for (Attachment a : [Select Id, Name, ContentType From Attachment Where ParentId = :so.Id])
        {   
            if (!a.Name.endsWith ('tif')) // Don't let TIFs get compared, as these can't be viewed by the viewer.
            {  

                if (a.ContentType.contains ('image/'))  // Only add images except TIFs to the list, ignore all other types
                {
                    myPhotos.add (new Photo (a.Id, a.Name));
                }
             
            }
        }
            
    }
                               
    public List<Photo> getPhotos ()
    {
        return myPhotos;
    }         
        
}

 

This is the apex page for cases, which doesn't work on the production org.

 

<apex:page standardController="Case" extensions="ImageViewController" showHeader="false" sidebar="false" standardStylesheets="false">
    
    <apex:styleSheet value="{!URLFOR($Resource.picbox,'picbox.css')}"/> 
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"/> 
    <apex:includeScript value="{!URLFOR($Resource.picbox,'picbox.js')}"/>
    
    
          <script>
               if (!/android|iphone|ipod|series60|symbian|windows ce|blackberry/i.test(navigator.userAgent)) {
                    jQuery(function($) {
                        $("a[rel^='lightbox']").picbox({/* Put custom options here */}, null, function(el) {
                        return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
                        });
                    });
               }
               
         </script>        
  

          <apex:repeat value="{!Photos}" var="p">
                <a rel="lightbox-viewer" href="{!p.url}"  title="{!p.name}">
                     <img width="150" height="150" alt="{!p.name}" src="{!p.url}" title="{!p.name}" />
                </a>
              
           </apex:repeat>

      
</apex:page>

 

This error comes up, when the page is called for a case with attached images:

 

Attempt to de-reference a null object
An unexpected error has occurred. Your development organization has been notified.

 

I am still a noob at Apex. One other question I have is how can I give the user an error message, when there are no image attachments in the case?

 

Any help would be appreciated...

 

Thanks.

 

Scott

crop1645crop1645

Scott

 

  1. Normally, you would debug this by going to Setup | Monitoring | Debug Logs - set up a debug log for the running user, repeat the test and then examine the log for the exact line number
  2. That said, I would guess your problem lies here:
    private void fetchPhotos ()
    {
        myPhotos.clear ();  // Empty list
        
        for (Attachment a : [Select Id, Name, ContentType From Attachment Where ParentId = :so.Id])
        {   
            if (!a.Name.endsWith ('tif')) // Don't let TIFs get compared, as these can't be viewed by the viewer.
            {  

                if (a.ContentType.contains ('image/'))  // Only add images except TIFs to the list, ignore all other types
                {
                    myPhotos.add (new Photo (a.Id, a.Name));
                }
             
            }
        }
            
    }

 If a.name is NULL, the a.name.endswith(..) will get an exception like you see (that is, an attachment without a name). Similarly, if a.contentType is NULL, the a.contentType.contains(..) will fail.  Take a look at your actual data and see if this is the situation

crop1645crop1645

Also - for the no images error message; use VF component apex:pageMessages and use in your controller an ApexPages.addMessage(...) statement. Consult the APEX doc for detailed examples -- you can set severity to Info, Warning, Error and the icon will display accordingly (benign to alarming)

Scott M - SFDC FanScott M - SFDC Fan

Thanks Eric.

 

I actually solved my problem by changing the logic.

 

This is what I have now.

 

private void fetchPhotos ()
    {
        myPhotos.clear ();  // Empty list
        
        for (Attachment a : [Select Id, Name, ContentType From Attachment Where ParentId = :so.Id])
        {   
        	            
            a.Name = a.Name.toLowerCase();      
            
            if (a.Name.endsWith ('tif') || a.Name.endsWith ('gif') || a.Name.endsWith ('jpg') || a.Name.endsWith ('jpeg')) //File is an image we want
            {  

                    myPhotos.add (new Photo (a.Id, a.Name));                    
             
            }
        }
            
    }

I still don't understand why my old code would work in our Sandbox, but not in the live system.

 

I'll look into the apex:pageMessages and ApexPages.addMessage(...) functions. Thanks for that.

 

Scott

crop1645crop1645

Well, you removed the test for a.contentType.contains(..) - perhaps you had some attachments without a contentType in one environment rather than another.

 

As best practice in APEX, you should be checking for null values before you do additional enumeration or primitive methods upon the object unless you know for 100% certainty that the value will be non null